@roj-ai/sdk 0.1.36 → 0.2.2

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 (925) 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 +25 -13
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +23 -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/index.d.ts +1 -0
  233. package/dist/plugins/git-status/index.d.ts.map +1 -1
  234. package/dist/plugins/git-status/plugin.d.ts +38 -7
  235. package/dist/plugins/git-status/plugin.d.ts.map +1 -1
  236. package/dist/plugins/git-status/plugin.js +169 -64
  237. package/dist/plugins/git-status/plugin.js.map +1 -1
  238. package/dist/plugins/llm-debug/plugin.d.ts.map +1 -1
  239. package/dist/plugins/llm-debug/plugin.js +1 -0
  240. package/dist/plugins/llm-debug/plugin.js.map +1 -1
  241. package/dist/plugins/logs/plugin.d.ts +1 -4
  242. package/dist/plugins/logs/plugin.d.ts.map +1 -1
  243. package/dist/plugins/logs/plugin.js +7 -0
  244. package/dist/plugins/logs/plugin.js.map +1 -1
  245. package/dist/plugins/mailbox/helpers.d.ts +2 -2
  246. package/dist/plugins/mailbox/helpers.js +1 -1
  247. package/dist/plugins/mailbox/plugin.d.ts.map +1 -1
  248. package/dist/plugins/mailbox/plugin.js +38 -43
  249. package/dist/plugins/mailbox/plugin.js.map +1 -1
  250. package/dist/plugins/mailbox/query.d.ts +7 -2
  251. package/dist/plugins/mailbox/query.d.ts.map +1 -1
  252. package/dist/plugins/mailbox/query.js +14 -7
  253. package/dist/plugins/mailbox/query.js.map +1 -1
  254. package/dist/plugins/mailbox/state.d.ts +5 -4
  255. package/dist/plugins/mailbox/state.d.ts.map +1 -1
  256. package/dist/plugins/mailbox/state.js +6 -5
  257. package/dist/plugins/mailbox/state.js.map +1 -1
  258. package/dist/plugins/resources/filename.d.ts +4 -0
  259. package/dist/plugins/resources/filename.d.ts.map +1 -0
  260. package/dist/plugins/resources/filename.js +18 -0
  261. package/dist/plugins/resources/filename.js.map +1 -0
  262. package/dist/plugins/resources/plugin.d.ts +3 -0
  263. package/dist/plugins/resources/plugin.d.ts.map +1 -1
  264. package/dist/plugins/resources/plugin.js +97 -60
  265. package/dist/plugins/resources/plugin.js.map +1 -1
  266. package/dist/plugins/resources/state.d.ts +1 -1
  267. package/dist/plugins/resources/state.js +1 -1
  268. package/dist/plugins/result-eviction/plugin.d.ts.map +1 -1
  269. package/dist/plugins/result-eviction/plugin.js +6 -1
  270. package/dist/plugins/result-eviction/plugin.js.map +1 -1
  271. package/dist/plugins/services/plugin.d.ts +4 -1
  272. package/dist/plugins/services/plugin.d.ts.map +1 -1
  273. package/dist/plugins/services/plugin.js +251 -100
  274. package/dist/plugins/services/plugin.js.map +1 -1
  275. package/dist/plugins/services/prompt.d.ts.map +1 -1
  276. package/dist/plugins/services/prompt.js +1 -4
  277. package/dist/plugins/services/prompt.js.map +1 -1
  278. package/dist/plugins/services/schema.d.ts +15 -5
  279. package/dist/plugins/services/schema.d.ts.map +1 -1
  280. package/dist/plugins/services/service.d.ts +100 -18
  281. package/dist/plugins/services/service.d.ts.map +1 -1
  282. package/dist/plugins/services/service.js +680 -230
  283. package/dist/plugins/services/service.js.map +1 -1
  284. package/dist/plugins/session-lifecycle/plugin.d.ts +21 -1
  285. package/dist/plugins/session-lifecycle/plugin.d.ts.map +1 -1
  286. package/dist/plugins/session-lifecycle/plugin.js +53 -40
  287. package/dist/plugins/session-lifecycle/plugin.js.map +1 -1
  288. package/dist/plugins/session-state/plugin.d.ts +21 -13
  289. package/dist/plugins/session-state/plugin.d.ts.map +1 -1
  290. package/dist/plugins/session-state/plugin.js +214 -79
  291. package/dist/plugins/session-state/plugin.js.map +1 -1
  292. package/dist/plugins/session-stats/plugin.d.ts.map +1 -1
  293. package/dist/plugins/session-stats/plugin.js +1 -0
  294. package/dist/plugins/session-stats/plugin.js.map +1 -1
  295. package/dist/plugins/shell/executor.d.ts +17 -15
  296. package/dist/plugins/shell/executor.d.ts.map +1 -1
  297. package/dist/plugins/shell/executor.js +130 -195
  298. package/dist/plugins/shell/executor.js.map +1 -1
  299. package/dist/plugins/shell/index.d.ts +2 -2
  300. package/dist/plugins/shell/index.d.ts.map +1 -1
  301. package/dist/plugins/shell/index.js +2 -2
  302. package/dist/plugins/shell/index.js.map +1 -1
  303. package/dist/plugins/shell/plugin.d.ts +5 -4
  304. package/dist/plugins/shell/plugin.d.ts.map +1 -1
  305. package/dist/plugins/shell/plugin.js +4 -8
  306. package/dist/plugins/shell/plugin.js.map +1 -1
  307. package/dist/plugins/skills/discovery.d.ts.map +1 -1
  308. package/dist/plugins/skills/discovery.js +10 -8
  309. package/dist/plugins/skills/discovery.js.map +1 -1
  310. package/dist/plugins/skills/index.d.ts +1 -1
  311. package/dist/plugins/skills/index.d.ts.map +1 -1
  312. package/dist/plugins/skills/plugin.d.ts +1 -1
  313. package/dist/plugins/skills/plugin.d.ts.map +1 -1
  314. package/dist/plugins/skills/plugin.js +23 -30
  315. package/dist/plugins/skills/plugin.js.map +1 -1
  316. package/dist/plugins/skills/prompts.d.ts +3 -3
  317. package/dist/plugins/skills/prompts.d.ts.map +1 -1
  318. package/dist/plugins/skills/prompts.js.map +1 -1
  319. package/dist/plugins/skills/schema.d.ts +4 -2
  320. package/dist/plugins/skills/schema.d.ts.map +1 -1
  321. package/dist/plugins/todo/schema.d.ts +1 -1
  322. package/dist/plugins/uploads/plugin.d.ts +11 -4
  323. package/dist/plugins/uploads/plugin.d.ts.map +1 -1
  324. package/dist/plugins/uploads/plugin.js +891 -225
  325. package/dist/plugins/uploads/plugin.js.map +1 -1
  326. package/dist/plugins/uploads/preprocessor.d.ts +14 -0
  327. package/dist/plugins/uploads/preprocessor.d.ts.map +1 -1
  328. package/dist/plugins/uploads/preprocessor.js +11 -0
  329. package/dist/plugins/uploads/preprocessor.js.map +1 -1
  330. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts +1 -1
  331. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts.map +1 -1
  332. package/dist/plugins/uploads/preprocessors/image-classifier.js +51 -26
  333. package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -1
  334. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts +2 -2
  335. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts.map +1 -1
  336. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +41 -16
  337. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -1
  338. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts +1 -1
  339. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts.map +1 -1
  340. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js +29 -14
  341. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js.map +1 -1
  342. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts +1 -1
  343. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts.map +1 -1
  344. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +62 -34
  345. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -1
  346. package/dist/plugins/uploads/schema.d.ts +25 -2
  347. package/dist/plugins/uploads/schema.d.ts.map +1 -1
  348. package/dist/plugins/uploads/schema.js +24 -3
  349. package/dist/plugins/uploads/schema.js.map +1 -1
  350. package/dist/plugins/uploads/state.d.ts +13 -1
  351. package/dist/plugins/uploads/state.d.ts.map +1 -1
  352. package/dist/plugins/uploads/state.js +4 -1
  353. package/dist/plugins/uploads/state.js.map +1 -1
  354. package/dist/plugins/user-chat/plugin.d.ts +12 -5
  355. package/dist/plugins/user-chat/plugin.d.ts.map +1 -1
  356. package/dist/plugins/user-chat/plugin.js +141 -32
  357. package/dist/plugins/user-chat/plugin.js.map +1 -1
  358. package/dist/plugins/workers/context.d.ts +35 -13
  359. package/dist/plugins/workers/context.d.ts.map +1 -1
  360. package/dist/plugins/workers/context.js +82 -32
  361. package/dist/plugins/workers/context.js.map +1 -1
  362. package/dist/plugins/workers/definition.d.ts +7 -0
  363. package/dist/plugins/workers/definition.d.ts.map +1 -1
  364. package/dist/plugins/workers/definition.js.map +1 -1
  365. package/dist/plugins/workers/index.d.ts +4 -4
  366. package/dist/plugins/workers/index.d.ts.map +1 -1
  367. package/dist/plugins/workers/index.js +2 -2
  368. package/dist/plugins/workers/index.js.map +1 -1
  369. package/dist/plugins/workers/plugin.d.ts +10 -57
  370. package/dist/plugins/workers/plugin.d.ts.map +1 -1
  371. package/dist/plugins/workers/plugin.js +385 -123
  372. package/dist/plugins/workers/plugin.js.map +1 -1
  373. package/dist/plugins/workers/state.d.ts +69 -0
  374. package/dist/plugins/workers/state.d.ts.map +1 -0
  375. package/dist/plugins/workers/state.js +52 -0
  376. package/dist/plugins/workers/state.js.map +1 -0
  377. package/dist/plugins/workers/worker.d.ts +15 -4
  378. package/dist/plugins/workers/worker.d.ts.map +1 -1
  379. package/dist/testing/conformance.d.ts +106 -0
  380. package/dist/testing/conformance.d.ts.map +1 -0
  381. package/dist/testing/conformance.js +1463 -0
  382. package/dist/testing/conformance.js.map +1 -0
  383. package/dist/testing/node-platform.d.ts.map +1 -1
  384. package/dist/testing/node-platform.js +5 -0
  385. package/dist/testing/node-platform.js.map +1 -1
  386. package/dist/testing/test-harness.d.ts +11 -1
  387. package/dist/testing/test-harness.d.ts.map +1 -1
  388. package/dist/testing/test-harness.js +17 -37
  389. package/dist/testing/test-harness.js.map +1 -1
  390. package/dist/testing/wait-helpers.d.ts.map +1 -1
  391. package/dist/testing/wait-helpers.js +1 -3
  392. package/dist/testing/wait-helpers.js.map +1 -1
  393. package/dist/transport/adapter/client-adapter.d.ts +6 -0
  394. package/dist/transport/adapter/client-adapter.d.ts.map +1 -1
  395. package/dist/transport/adapter/client-adapter.js +50 -3
  396. package/dist/transport/adapter/client-adapter.js.map +1 -1
  397. package/dist/transport/adapter/heartbeat.d.ts +16 -0
  398. package/dist/transport/adapter/heartbeat.d.ts.map +1 -0
  399. package/dist/transport/adapter/heartbeat.js +41 -0
  400. package/dist/transport/adapter/heartbeat.js.map +1 -0
  401. package/dist/transport/adapter/server-adapter.d.ts.map +1 -1
  402. package/dist/transport/adapter/server-adapter.js +6 -0
  403. package/dist/transport/adapter/server-adapter.js.map +1 -1
  404. package/dist/transport/http/app.d.ts +3 -30
  405. package/dist/transport/http/app.d.ts.map +1 -1
  406. package/dist/transport/http/app.js +3 -7
  407. package/dist/transport/http/app.js.map +1 -1
  408. package/dist/transport/http/context.d.ts +40 -0
  409. package/dist/transport/http/context.d.ts.map +1 -0
  410. package/dist/transport/http/context.js +17 -0
  411. package/dist/transport/http/context.js.map +1 -0
  412. package/dist/transport/http/fetch-guard.d.ts +49 -0
  413. package/dist/transport/http/fetch-guard.d.ts.map +1 -0
  414. package/dist/transport/http/fetch-guard.js +312 -0
  415. package/dist/transport/http/fetch-guard.js.map +1 -0
  416. package/dist/transport/http/index.d.ts +1 -1
  417. package/dist/transport/http/index.d.ts.map +1 -1
  418. package/dist/transport/http/middleware/bearer-auth.d.ts +1 -1
  419. package/dist/transport/http/middleware/bearer-auth.d.ts.map +1 -1
  420. package/dist/transport/http/middleware/error-handler.d.ts +2 -2
  421. package/dist/transport/http/middleware/error-handler.d.ts.map +1 -1
  422. package/dist/transport/http/path-containment.d.ts +20 -0
  423. package/dist/transport/http/path-containment.d.ts.map +1 -0
  424. package/dist/transport/http/path-containment.js +31 -0
  425. package/dist/transport/http/path-containment.js.map +1 -0
  426. package/dist/transport/http/responses.d.ts +30 -0
  427. package/dist/transport/http/responses.d.ts.map +1 -0
  428. package/dist/transport/http/responses.js +5 -0
  429. package/dist/transport/http/responses.js.map +1 -0
  430. package/dist/transport/http/routes/files.d.ts +1 -1
  431. package/dist/transport/http/routes/files.d.ts.map +1 -1
  432. package/dist/transport/http/routes/files.js +54 -155
  433. package/dist/transport/http/routes/files.js.map +1 -1
  434. package/dist/transport/http/routes/resources.d.ts +1 -1
  435. package/dist/transport/http/routes/resources.d.ts.map +1 -1
  436. package/dist/transport/http/routes/resources.js +92 -57
  437. package/dist/transport/http/routes/resources.js.map +1 -1
  438. package/dist/transport/http/routes/rpc.d.ts +6 -1
  439. package/dist/transport/http/routes/rpc.d.ts.map +1 -1
  440. package/dist/transport/http/routes/rpc.js +51 -21
  441. package/dist/transport/http/routes/rpc.js.map +1 -1
  442. package/dist/transport/http/routes/upload.d.ts +1 -1
  443. package/dist/transport/http/routes/upload.d.ts.map +1 -1
  444. package/dist/transport/http/routes/upload.js +256 -169
  445. package/dist/transport/http/routes/upload.js.map +1 -1
  446. package/dist/user-config.d.ts +34 -7
  447. package/dist/user-config.d.ts.map +1 -1
  448. package/dist/user-config.js +71 -0
  449. package/dist/user-config.js.map +1 -1
  450. package/package.json +17 -7
  451. package/src/bootstrap.ts +119 -35
  452. package/src/bun-platform/fs.ts +1 -0
  453. package/src/bun-platform/index.ts +18 -1
  454. package/src/bun-platform/server-lifecycle.ts +218 -0
  455. package/src/bun-platform/shell.ts +362 -0
  456. package/src/config.ts +130 -0
  457. package/src/core/agents/agent.ts +210 -92
  458. package/src/core/agents/config.ts +8 -0
  459. package/src/core/agents/retry.ts +16 -17
  460. package/src/core/agents/state.ts +2 -0
  461. package/src/core/events/base-event-store.ts +24 -16
  462. package/src/core/events/file.ts +198 -22
  463. package/src/core/file-store/containment.ts +75 -0
  464. package/src/core/file-store/file-store.ts +106 -25
  465. package/src/core/file-store/types.ts +14 -1
  466. package/src/core/image/image-processor.ts +3 -1
  467. package/src/core/image/types.ts +2 -0
  468. package/src/core/image/vips-resizer.ts +102 -37
  469. package/src/core/llm/anthropic.ts +63 -79
  470. package/src/core/llm/logger.ts +175 -37
  471. package/src/core/llm/openrouter.ts +57 -72
  472. package/src/core/llm/provider-request.ts +40 -0
  473. package/src/core/llm/provider.ts +28 -0
  474. package/src/core/plugins/plugin-builder.ts +106 -14
  475. package/src/core/preset/preset-builder.ts +12 -22
  476. package/src/core/sessions/context.ts +18 -0
  477. package/src/core/sessions/runtime-activity.ts +78 -0
  478. package/src/core/sessions/schema.ts +29 -3
  479. package/src/core/sessions/session-manager.ts +560 -140
  480. package/src/core/sessions/session-store.ts +38 -0
  481. package/src/core/sessions/session.ts +187 -47
  482. package/src/core/sessions/state.ts +11 -0
  483. package/src/core/system.ts +15 -0
  484. package/src/core/wake-key.ts +65 -0
  485. package/src/index.ts +32 -12
  486. package/src/lib/archive/archive-inspection.fixtures.ts +138 -0
  487. package/src/lib/archive/archive-inspection.ts +359 -0
  488. package/src/lib/archive/index.ts +17 -0
  489. package/src/lib/logger/console.ts +7 -57
  490. package/src/lib/logger/file.ts +28 -50
  491. package/src/lib/logger/index.ts +3 -1
  492. package/src/lib/logger/jsonl.ts +36 -0
  493. package/src/lib/logger/logger.ts +48 -0
  494. package/src/lib/logger/session-log.ts +42 -0
  495. package/src/lib/utils/concurrency.ts +37 -8
  496. package/src/lib/utils/fs-batch.ts +49 -0
  497. package/src/lib/utils/result.ts +7 -31
  498. package/src/lib/utils/sleep.ts +23 -0
  499. package/src/platform/fs-revision.ts +21 -0
  500. package/src/platform/fs.ts +109 -1
  501. package/src/platform/git.ts +67 -0
  502. package/src/platform/index.ts +51 -1
  503. package/src/platform/llm-call-log.ts +86 -0
  504. package/src/platform/scheduler.ts +71 -0
  505. package/src/platform/session-log.ts +39 -0
  506. package/src/platform/shell.ts +89 -0
  507. package/src/plugins/agent-status/plugin.ts +1 -0
  508. package/src/plugins/agents/plugin.ts +134 -81
  509. package/src/plugins/filesystem/listing.ts +70 -12
  510. package/src/plugins/filesystem/plugin.ts +8 -6
  511. package/src/plugins/git-status/index.ts +1 -0
  512. package/src/plugins/git-status/plugin.ts +211 -77
  513. package/src/plugins/llm-debug/plugin.ts +1 -0
  514. package/src/plugins/logs/plugin.ts +9 -0
  515. package/src/plugins/mailbox/plugin.ts +46 -64
  516. package/src/plugins/mailbox/query.ts +15 -7
  517. package/src/plugins/mailbox/state.ts +1 -0
  518. package/src/plugins/resources/filename.ts +19 -0
  519. package/src/plugins/resources/plugin.ts +111 -59
  520. package/src/plugins/result-eviction/plugin.ts +6 -1
  521. package/src/plugins/services/plugin.ts +254 -98
  522. package/src/plugins/services/prompt.ts +1 -6
  523. package/src/plugins/services/schema.ts +17 -3
  524. package/src/plugins/services/service.ts +702 -252
  525. package/src/plugins/session-lifecycle/plugin.ts +56 -41
  526. package/src/plugins/session-state/plugin.ts +242 -88
  527. package/src/plugins/session-stats/plugin.ts +1 -0
  528. package/src/plugins/shell/executor.ts +144 -226
  529. package/src/plugins/shell/index.ts +1 -4
  530. package/src/plugins/shell/plugin.ts +7 -9
  531. package/src/plugins/skills/discovery.ts +10 -8
  532. package/src/plugins/skills/index.ts +1 -1
  533. package/src/plugins/skills/plugin.ts +19 -27
  534. package/src/plugins/skills/prompts.ts +3 -3
  535. package/src/plugins/skills/schema.ts +5 -2
  536. package/src/plugins/uploads/plugin.ts +991 -273
  537. package/src/plugins/uploads/preprocessor.ts +25 -0
  538. package/src/plugins/uploads/preprocessors/image-classifier.ts +56 -25
  539. package/src/plugins/uploads/preprocessors/markitdown-preprocessor.ts +41 -15
  540. package/src/plugins/uploads/preprocessors/pdf-preprocessor.ts +32 -16
  541. package/src/plugins/uploads/preprocessors/zip-preprocessor.ts +67 -38
  542. package/src/plugins/uploads/schema.ts +30 -3
  543. package/src/plugins/uploads/state.ts +12 -0
  544. package/src/plugins/user-chat/plugin.ts +196 -40
  545. package/src/plugins/workers/context.ts +102 -39
  546. package/src/plugins/workers/definition.ts +7 -0
  547. package/src/plugins/workers/index.ts +4 -4
  548. package/src/plugins/workers/plugin.ts +461 -151
  549. package/src/plugins/workers/state.ts +64 -0
  550. package/src/plugins/workers/worker.ts +15 -4
  551. package/src/testing/conformance.ts +1751 -0
  552. package/src/testing/node-platform.ts +5 -0
  553. package/src/testing/test-harness.ts +21 -38
  554. package/src/testing/wait-helpers.ts +1 -4
  555. package/src/transport/adapter/client-adapter.ts +60 -3
  556. package/src/transport/adapter/heartbeat.ts +50 -0
  557. package/src/transport/adapter/server-adapter.ts +6 -0
  558. package/src/transport/http/app.ts +7 -35
  559. package/src/transport/http/context.ts +46 -0
  560. package/src/transport/http/fetch-guard.ts +318 -0
  561. package/src/transport/http/index.ts +1 -1
  562. package/src/transport/http/middleware/bearer-auth.ts +1 -1
  563. package/src/transport/http/middleware/error-handler.ts +1 -1
  564. package/src/transport/http/path-containment.ts +44 -0
  565. package/src/transport/http/responses.ts +20 -0
  566. package/src/transport/http/routes/files.ts +69 -159
  567. package/src/transport/http/routes/resources.ts +124 -93
  568. package/src/transport/http/routes/rpc.ts +63 -26
  569. package/src/transport/http/routes/upload.ts +327 -258
  570. package/src/user-config.ts +93 -7
  571. package/dist/config.test.d.ts +0 -2
  572. package/dist/config.test.d.ts.map +0 -1
  573. package/dist/config.test.js +0 -155
  574. package/dist/config.test.js.map +0 -1
  575. package/dist/core/agent-loop.integration.test.d.ts +0 -2
  576. package/dist/core/agent-loop.integration.test.d.ts.map +0 -1
  577. package/dist/core/agent-loop.integration.test.js +0 -414
  578. package/dist/core/agent-loop.integration.test.js.map +0 -1
  579. package/dist/core/agents/agent-config.test.d.ts +0 -2
  580. package/dist/core/agents/agent-config.test.d.ts.map +0 -1
  581. package/dist/core/agents/agent-config.test.js +0 -194
  582. package/dist/core/agents/agent-config.test.js.map +0 -1
  583. package/dist/core/agents/agent-shutdown.test.d.ts +0 -6
  584. package/dist/core/agents/agent-shutdown.test.d.ts.map +0 -1
  585. package/dist/core/agents/agent-shutdown.test.js +0 -180
  586. package/dist/core/agents/agent-shutdown.test.js.map +0 -1
  587. package/dist/core/agents/agent.test.d.ts +0 -2
  588. package/dist/core/agents/agent.test.d.ts.map +0 -1
  589. package/dist/core/agents/agent.test.js +0 -313
  590. package/dist/core/agents/agent.test.js.map +0 -1
  591. package/dist/core/agents/communicator.d.ts +0 -3
  592. package/dist/core/agents/communicator.d.ts.map +0 -1
  593. package/dist/core/agents/communicator.js +0 -13
  594. package/dist/core/agents/communicator.js.map +0 -1
  595. package/dist/core/agents/handler-events.test.d.ts +0 -5
  596. package/dist/core/agents/handler-events.test.d.ts.map +0 -1
  597. package/dist/core/agents/handler-events.test.js +0 -115
  598. package/dist/core/agents/handler-events.test.js.map +0 -1
  599. package/dist/core/agents/response-sanitizer.test.d.ts +0 -2
  600. package/dist/core/agents/response-sanitizer.test.d.ts.map +0 -1
  601. package/dist/core/agents/response-sanitizer.test.js +0 -101
  602. package/dist/core/agents/response-sanitizer.test.js.map +0 -1
  603. package/dist/core/error-recovery.integration.test.d.ts +0 -2
  604. package/dist/core/error-recovery.integration.test.d.ts.map +0 -1
  605. package/dist/core/error-recovery.integration.test.js +0 -288
  606. package/dist/core/error-recovery.integration.test.js.map +0 -1
  607. package/dist/core/event-sourcing.integration.test.d.ts +0 -2
  608. package/dist/core/event-sourcing.integration.test.d.ts.map +0 -1
  609. package/dist/core/event-sourcing.integration.test.js +0 -154
  610. package/dist/core/event-sourcing.integration.test.js.map +0 -1
  611. package/dist/core/events/file.test.d.ts +0 -2
  612. package/dist/core/events/file.test.d.ts.map +0 -1
  613. package/dist/core/events/file.test.js +0 -284
  614. package/dist/core/events/file.test.js.map +0 -1
  615. package/dist/core/events/memory.test.d.ts +0 -2
  616. package/dist/core/events/memory.test.d.ts.map +0 -1
  617. package/dist/core/events/memory.test.js +0 -502
  618. package/dist/core/events/memory.test.js.map +0 -1
  619. package/dist/core/image/image-processor.test.d.ts +0 -2
  620. package/dist/core/image/image-processor.test.d.ts.map +0 -1
  621. package/dist/core/image/image-processor.test.js +0 -171
  622. package/dist/core/image/image-processor.test.js.map +0 -1
  623. package/dist/core/image/vips-resizer.test.d.ts +0 -2
  624. package/dist/core/image/vips-resizer.test.d.ts.map +0 -1
  625. package/dist/core/image/vips-resizer.test.js +0 -336
  626. package/dist/core/image/vips-resizer.test.js.map +0 -1
  627. package/dist/core/llm/anthropic.test.d.ts +0 -2
  628. package/dist/core/llm/anthropic.test.d.ts.map +0 -1
  629. package/dist/core/llm/anthropic.test.js +0 -464
  630. package/dist/core/llm/anthropic.test.js.map +0 -1
  631. package/dist/core/llm/cache-breakpoints.test.d.ts +0 -2
  632. package/dist/core/llm/cache-breakpoints.test.d.ts.map +0 -1
  633. package/dist/core/llm/cache-breakpoints.test.js +0 -69
  634. package/dist/core/llm/cache-breakpoints.test.js.map +0 -1
  635. package/dist/core/llm/cache-live.test.d.ts +0 -16
  636. package/dist/core/llm/cache-live.test.d.ts.map +0 -1
  637. package/dist/core/llm/cache-live.test.js +0 -137
  638. package/dist/core/llm/cache-live.test.js.map +0 -1
  639. package/dist/core/llm/logger.test.d.ts +0 -7
  640. package/dist/core/llm/logger.test.d.ts.map +0 -1
  641. package/dist/core/llm/logger.test.js +0 -228
  642. package/dist/core/llm/logger.test.js.map +0 -1
  643. package/dist/core/llm/message-sanitization.test.d.ts +0 -2
  644. package/dist/core/llm/message-sanitization.test.d.ts.map +0 -1
  645. package/dist/core/llm/message-sanitization.test.js +0 -181
  646. package/dist/core/llm/message-sanitization.test.js.map +0 -1
  647. package/dist/core/llm/mock.test.d.ts +0 -2
  648. package/dist/core/llm/mock.test.d.ts.map +0 -1
  649. package/dist/core/llm/mock.test.js +0 -318
  650. package/dist/core/llm/mock.test.js.map +0 -1
  651. package/dist/core/llm/model-shortlist-live.test.d.ts +0 -35
  652. package/dist/core/llm/model-shortlist-live.test.d.ts.map +0 -1
  653. package/dist/core/llm/model-shortlist-live.test.js +0 -452
  654. package/dist/core/llm/model-shortlist-live.test.js.map +0 -1
  655. package/dist/core/llm/openrouter-mapping.test.d.ts +0 -2
  656. package/dist/core/llm/openrouter-mapping.test.d.ts.map +0 -1
  657. package/dist/core/llm/openrouter-mapping.test.js +0 -190
  658. package/dist/core/llm/openrouter-mapping.test.js.map +0 -1
  659. package/dist/core/llm/openrouter.test.d.ts +0 -2
  660. package/dist/core/llm/openrouter.test.d.ts.map +0 -1
  661. package/dist/core/llm/openrouter.test.js +0 -377
  662. package/dist/core/llm/openrouter.test.js.map +0 -1
  663. package/dist/core/llm/provider-integration.test.d.ts +0 -12
  664. package/dist/core/llm/provider-integration.test.d.ts.map +0 -1
  665. package/dist/core/llm/provider-integration.test.js +0 -350
  666. package/dist/core/llm/provider-integration.test.js.map +0 -1
  667. package/dist/core/llm/reasoning-details.test.d.ts +0 -2
  668. package/dist/core/llm/reasoning-details.test.d.ts.map +0 -1
  669. package/dist/core/llm/reasoning-details.test.js +0 -144
  670. package/dist/core/llm/reasoning-details.test.js.map +0 -1
  671. package/dist/core/llm/routing-provider.test.d.ts +0 -2
  672. package/dist/core/llm/routing-provider.test.d.ts.map +0 -1
  673. package/dist/core/llm/routing-provider.test.js +0 -94
  674. package/dist/core/llm/routing-provider.test.js.map +0 -1
  675. package/dist/core/llm/snapshot-middleware.test.d.ts +0 -2
  676. package/dist/core/llm/snapshot-middleware.test.d.ts.map +0 -1
  677. package/dist/core/llm/snapshot-middleware.test.js +0 -144
  678. package/dist/core/llm/snapshot-middleware.test.js.map +0 -1
  679. package/dist/core/llm/thinking-blocks.test.d.ts +0 -2
  680. package/dist/core/llm/thinking-blocks.test.d.ts.map +0 -1
  681. package/dist/core/llm/thinking-blocks.test.js +0 -291
  682. package/dist/core/llm/thinking-blocks.test.js.map +0 -1
  683. package/dist/core/multi-agent.integration.test.d.ts +0 -2
  684. package/dist/core/multi-agent.integration.test.d.ts.map +0 -1
  685. package/dist/core/multi-agent.integration.test.js +0 -298
  686. package/dist/core/multi-agent.integration.test.js.map +0 -1
  687. package/dist/core/plugin-hooks.integration.test.d.ts +0 -2
  688. package/dist/core/plugin-hooks.integration.test.d.ts.map +0 -1
  689. package/dist/core/plugin-hooks.integration.test.js +0 -458
  690. package/dist/core/plugin-hooks.integration.test.js.map +0 -1
  691. package/dist/core/reasoning-round-trip.integration.test.d.ts +0 -2
  692. package/dist/core/reasoning-round-trip.integration.test.d.ts.map +0 -1
  693. package/dist/core/reasoning-round-trip.integration.test.js +0 -150
  694. package/dist/core/reasoning-round-trip.integration.test.js.map +0 -1
  695. package/dist/core/session-lifecycle.integration.test.d.ts +0 -2
  696. package/dist/core/session-lifecycle.integration.test.d.ts.map +0 -1
  697. package/dist/core/session-lifecycle.integration.test.js +0 -159
  698. package/dist/core/session-lifecycle.integration.test.js.map +0 -1
  699. package/dist/core/sessions/fork-utils.test.d.ts +0 -2
  700. package/dist/core/sessions/fork-utils.test.d.ts.map +0 -1
  701. package/dist/core/sessions/fork-utils.test.js +0 -129
  702. package/dist/core/sessions/fork-utils.test.js.map +0 -1
  703. package/dist/core/sessions/session-overrides.integration.test.d.ts +0 -2
  704. package/dist/core/sessions/session-overrides.integration.test.d.ts.map +0 -1
  705. package/dist/core/sessions/session-overrides.integration.test.js +0 -154
  706. package/dist/core/sessions/session-overrides.integration.test.js.map +0 -1
  707. package/dist/core/sessions/session.test.d.ts +0 -2
  708. package/dist/core/sessions/session.test.d.ts.map +0 -1
  709. package/dist/core/sessions/session.test.js +0 -1100
  710. package/dist/core/sessions/session.test.js.map +0 -1
  711. package/dist/core/tools/executor.test.d.ts +0 -2
  712. package/dist/core/tools/executor.test.d.ts.map +0 -1
  713. package/dist/core/tools/executor.test.js +0 -144
  714. package/dist/core/tools/executor.test.js.map +0 -1
  715. package/dist/lib/logger/console.test.d.ts +0 -2
  716. package/dist/lib/logger/console.test.d.ts.map +0 -1
  717. package/dist/lib/logger/console.test.js +0 -258
  718. package/dist/lib/logger/console.test.js.map +0 -1
  719. package/dist/lib/never.d.ts +0 -2
  720. package/dist/lib/never.d.ts.map +0 -1
  721. package/dist/lib/never.js +0 -4
  722. package/dist/lib/never.js.map +0 -1
  723. package/dist/lib/utils/concurrency.test.d.ts +0 -2
  724. package/dist/lib/utils/concurrency.test.d.ts.map +0 -1
  725. package/dist/lib/utils/concurrency.test.js +0 -135
  726. package/dist/lib/utils/concurrency.test.js.map +0 -1
  727. package/dist/plugins/agent-status/agent-status.test.d.ts +0 -2
  728. package/dist/plugins/agent-status/agent-status.test.d.ts.map +0 -1
  729. package/dist/plugins/agent-status/agent-status.test.js +0 -136
  730. package/dist/plugins/agent-status/agent-status.test.js.map +0 -1
  731. package/dist/plugins/agents/agents.integration.test.d.ts +0 -2
  732. package/dist/plugins/agents/agents.integration.test.d.ts.map +0 -1
  733. package/dist/plugins/agents/agents.integration.test.js +0 -830
  734. package/dist/plugins/agents/agents.integration.test.js.map +0 -1
  735. package/dist/plugins/agents/supervision.integration.test.d.ts +0 -2
  736. package/dist/plugins/agents/supervision.integration.test.d.ts.map +0 -1
  737. package/dist/plugins/agents/supervision.integration.test.js +0 -215
  738. package/dist/plugins/agents/supervision.integration.test.js.map +0 -1
  739. package/dist/plugins/context-compact/compaction-live.test.d.ts +0 -17
  740. package/dist/plugins/context-compact/compaction-live.test.d.ts.map +0 -1
  741. package/dist/plugins/context-compact/compaction-live.test.js +0 -177
  742. package/dist/plugins/context-compact/compaction-live.test.js.map +0 -1
  743. package/dist/plugins/context-compact/context-compact.integration.test.d.ts +0 -2
  744. package/dist/plugins/context-compact/context-compact.integration.test.d.ts.map +0 -1
  745. package/dist/plugins/context-compact/context-compact.integration.test.js +0 -364
  746. package/dist/plugins/context-compact/context-compact.integration.test.js.map +0 -1
  747. package/dist/plugins/context-compact/context-compactor.test.d.ts +0 -2
  748. package/dist/plugins/context-compact/context-compactor.test.d.ts.map +0 -1
  749. package/dist/plugins/context-compact/context-compactor.test.js +0 -858
  750. package/dist/plugins/context-compact/context-compactor.test.js.map +0 -1
  751. package/dist/plugins/context-compact/history-offloader.test.d.ts +0 -2
  752. package/dist/plugins/context-compact/history-offloader.test.d.ts.map +0 -1
  753. package/dist/plugins/context-compact/history-offloader.test.js +0 -77
  754. package/dist/plugins/context-compact/history-offloader.test.js.map +0 -1
  755. package/dist/plugins/filesystem/filesystem.integration.test.d.ts +0 -2
  756. package/dist/plugins/filesystem/filesystem.integration.test.d.ts.map +0 -1
  757. package/dist/plugins/filesystem/filesystem.integration.test.js +0 -447
  758. package/dist/plugins/filesystem/filesystem.integration.test.js.map +0 -1
  759. package/dist/plugins/filesystem/schema.d.ts +0 -7
  760. package/dist/plugins/filesystem/schema.d.ts.map +0 -1
  761. package/dist/plugins/filesystem/schema.js +0 -2
  762. package/dist/plugins/filesystem/schema.js.map +0 -1
  763. package/dist/plugins/limits-guard/limit-guard.test.d.ts +0 -2
  764. package/dist/plugins/limits-guard/limit-guard.test.d.ts.map +0 -1
  765. package/dist/plugins/limits-guard/limit-guard.test.js +0 -194
  766. package/dist/plugins/limits-guard/limit-guard.test.js.map +0 -1
  767. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts +0 -2
  768. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts.map +0 -1
  769. package/dist/plugins/limits-guard/limits-guard.integration.test.js +0 -887
  770. package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +0 -1
  771. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts +0 -2
  772. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts.map +0 -1
  773. package/dist/plugins/llm-debug/llm-debug.integration.test.js +0 -157
  774. package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +0 -1
  775. package/dist/plugins/mailbox/mailbox.integration.test.d.ts +0 -2
  776. package/dist/plugins/mailbox/mailbox.integration.test.d.ts.map +0 -1
  777. package/dist/plugins/mailbox/mailbox.integration.test.js +0 -678
  778. package/dist/plugins/mailbox/mailbox.integration.test.js.map +0 -1
  779. package/dist/plugins/resources/resources.integration.test.d.ts +0 -2
  780. package/dist/plugins/resources/resources.integration.test.d.ts.map +0 -1
  781. package/dist/plugins/resources/resources.integration.test.js +0 -62
  782. package/dist/plugins/resources/resources.integration.test.js.map +0 -1
  783. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts +0 -2
  784. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts.map +0 -1
  785. package/dist/plugins/result-eviction/result-eviction.integration.test.js +0 -294
  786. package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +0 -1
  787. package/dist/plugins/services/pid-registry.test.d.ts +0 -2
  788. package/dist/plugins/services/pid-registry.test.d.ts.map +0 -1
  789. package/dist/plugins/services/pid-registry.test.js +0 -161
  790. package/dist/plugins/services/pid-registry.test.js.map +0 -1
  791. package/dist/plugins/services/services.integration.test.d.ts +0 -2
  792. package/dist/plugins/services/services.integration.test.d.ts.map +0 -1
  793. package/dist/plugins/services/services.integration.test.js +0 -1057
  794. package/dist/plugins/services/services.integration.test.js.map +0 -1
  795. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts +0 -2
  796. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts.map +0 -1
  797. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +0 -498
  798. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +0 -1
  799. package/dist/plugins/session-stats/plugin.test.d.ts +0 -2
  800. package/dist/plugins/session-stats/plugin.test.d.ts.map +0 -1
  801. package/dist/plugins/session-stats/plugin.test.js +0 -145
  802. package/dist/plugins/session-stats/plugin.test.js.map +0 -1
  803. package/dist/plugins/shell/shell.integration.test.d.ts +0 -2
  804. package/dist/plugins/shell/shell.integration.test.d.ts.map +0 -1
  805. package/dist/plugins/shell/shell.integration.test.js +0 -234
  806. package/dist/plugins/shell/shell.integration.test.js.map +0 -1
  807. package/dist/plugins/shell/shell.test.d.ts +0 -2
  808. package/dist/plugins/shell/shell.test.d.ts.map +0 -1
  809. package/dist/plugins/shell/shell.test.js +0 -236
  810. package/dist/plugins/shell/shell.test.js.map +0 -1
  811. package/dist/plugins/skills/discovery.test.d.ts +0 -2
  812. package/dist/plugins/skills/discovery.test.d.ts.map +0 -1
  813. package/dist/plugins/skills/discovery.test.js +0 -312
  814. package/dist/plugins/skills/discovery.test.js.map +0 -1
  815. package/dist/plugins/skills/skills.integration.test.d.ts +0 -2
  816. package/dist/plugins/skills/skills.integration.test.d.ts.map +0 -1
  817. package/dist/plugins/skills/skills.integration.test.js +0 -475
  818. package/dist/plugins/skills/skills.integration.test.js.map +0 -1
  819. package/dist/plugins/todo/todo.integration.test.d.ts +0 -2
  820. package/dist/plugins/todo/todo.integration.test.d.ts.map +0 -1
  821. package/dist/plugins/todo/todo.integration.test.js +0 -605
  822. package/dist/plugins/todo/todo.integration.test.js.map +0 -1
  823. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts +0 -2
  824. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts.map +0 -1
  825. package/dist/plugins/uploads/preprocessors/image-classifier.test.js +0 -113
  826. package/dist/plugins/uploads/preprocessors/image-classifier.test.js.map +0 -1
  827. package/dist/plugins/uploads/uploads.integration.test.d.ts +0 -2
  828. package/dist/plugins/uploads/uploads.integration.test.d.ts.map +0 -1
  829. package/dist/plugins/uploads/uploads.integration.test.js +0 -639
  830. package/dist/plugins/uploads/uploads.integration.test.js.map +0 -1
  831. package/dist/plugins/user-chat/user-chat.integration.test.d.ts +0 -2
  832. package/dist/plugins/user-chat/user-chat.integration.test.d.ts.map +0 -1
  833. package/dist/plugins/user-chat/user-chat.integration.test.js +0 -754
  834. package/dist/plugins/user-chat/user-chat.integration.test.js.map +0 -1
  835. package/dist/plugins/workers/workers.integration.test.d.ts +0 -2
  836. package/dist/plugins/workers/workers.integration.test.d.ts.map +0 -1
  837. package/dist/plugins/workers/workers.integration.test.js +0 -629
  838. package/dist/plugins/workers/workers.integration.test.js.map +0 -1
  839. package/dist/prompts/macros.test.d.ts +0 -2
  840. package/dist/prompts/macros.test.d.ts.map +0 -1
  841. package/dist/prompts/macros.test.js +0 -80
  842. package/dist/prompts/macros.test.js.map +0 -1
  843. package/dist/testing/test-harness.test.d.ts +0 -2
  844. package/dist/testing/test-harness.test.d.ts.map +0 -1
  845. package/dist/testing/test-harness.test.js +0 -92
  846. package/dist/testing/test-harness.test.js.map +0 -1
  847. package/dist/transport/http/routes/rpc.integration.test.d.ts +0 -2
  848. package/dist/transport/http/routes/rpc.integration.test.d.ts.map +0 -1
  849. package/dist/transport/http/routes/rpc.integration.test.js +0 -189
  850. package/dist/transport/http/routes/rpc.integration.test.js.map +0 -1
  851. package/dist/transport/http/routes/rpc.test.d.ts +0 -2
  852. package/dist/transport/http/routes/rpc.test.d.ts.map +0 -1
  853. package/dist/transport/http/routes/rpc.test.js +0 -316
  854. package/dist/transport/http/routes/rpc.test.js.map +0 -1
  855. package/src/config.test.ts +0 -174
  856. package/src/core/agent-loop.integration.test.ts +0 -503
  857. package/src/core/agents/agent-config.test.ts +0 -240
  858. package/src/core/agents/agent-shutdown.test.ts +0 -236
  859. package/src/core/agents/agent.test.ts +0 -387
  860. package/src/core/agents/communicator.ts +0 -16
  861. package/src/core/agents/handler-events.test.ts +0 -167
  862. package/src/core/agents/response-sanitizer.test.ts +0 -137
  863. package/src/core/error-recovery.integration.test.ts +0 -343
  864. package/src/core/event-sourcing.integration.test.ts +0 -191
  865. package/src/core/events/file.test.ts +0 -436
  866. package/src/core/events/memory.test.ts +0 -741
  867. package/src/core/image/image-processor.test.ts +0 -218
  868. package/src/core/image/vips-resizer.test.ts +0 -388
  869. package/src/core/llm/anthropic.test.ts +0 -546
  870. package/src/core/llm/cache-breakpoints.test.ts +0 -85
  871. package/src/core/llm/cache-live.test.ts +0 -155
  872. package/src/core/llm/logger.test.ts +0 -270
  873. package/src/core/llm/message-sanitization.test.ts +0 -217
  874. package/src/core/llm/mock.test.ts +0 -402
  875. package/src/core/llm/model-shortlist-live.test.ts +0 -577
  876. package/src/core/llm/openrouter-mapping.test.ts +0 -234
  877. package/src/core/llm/openrouter.test.ts +0 -499
  878. package/src/core/llm/provider-integration.test.ts +0 -408
  879. package/src/core/llm/reasoning-details.test.ts +0 -177
  880. package/src/core/llm/routing-provider.test.ts +0 -113
  881. package/src/core/llm/snapshot-middleware.test.ts +0 -168
  882. package/src/core/llm/thinking-blocks.test.ts +0 -345
  883. package/src/core/multi-agent.integration.test.ts +0 -340
  884. package/src/core/plugin-hooks.integration.test.ts +0 -568
  885. package/src/core/reasoning-round-trip.integration.test.ts +0 -188
  886. package/src/core/session-lifecycle.integration.test.ts +0 -202
  887. package/src/core/sessions/fork-utils.test.ts +0 -158
  888. package/src/core/sessions/session-overrides.integration.test.ts +0 -210
  889. package/src/core/sessions/session.test.ts +0 -1736
  890. package/src/core/tools/executor.test.ts +0 -161
  891. package/src/lib/logger/console.test.ts +0 -348
  892. package/src/lib/never.ts +0 -3
  893. package/src/lib/utils/concurrency.test.ts +0 -169
  894. package/src/plugins/agent-status/agent-status.test.ts +0 -164
  895. package/src/plugins/agents/agents.integration.test.ts +0 -976
  896. package/src/plugins/agents/supervision.integration.test.ts +0 -249
  897. package/src/plugins/context-compact/compaction-live.test.ts +0 -221
  898. package/src/plugins/context-compact/context-compact.integration.test.ts +0 -418
  899. package/src/plugins/context-compact/context-compactor.test.ts +0 -1036
  900. package/src/plugins/context-compact/history-offloader.test.ts +0 -100
  901. package/src/plugins/filesystem/filesystem.integration.test.ts +0 -529
  902. package/src/plugins/filesystem/schema.ts +0 -6
  903. package/src/plugins/limits-guard/limit-guard.test.ts +0 -253
  904. package/src/plugins/limits-guard/limits-guard.integration.test.ts +0 -1012
  905. package/src/plugins/llm-debug/llm-debug.integration.test.ts +0 -192
  906. package/src/plugins/mailbox/mailbox.integration.test.ts +0 -794
  907. package/src/plugins/resources/resources.integration.test.ts +0 -68
  908. package/src/plugins/result-eviction/result-eviction.integration.test.ts +0 -332
  909. package/src/plugins/services/pid-registry.test.ts +0 -180
  910. package/src/plugins/services/services.integration.test.ts +0 -1223
  911. package/src/plugins/session-lifecycle/session-lifecycle.integration.test.ts +0 -639
  912. package/src/plugins/session-stats/plugin.test.ts +0 -160
  913. package/src/plugins/shell/shell.integration.test.ts +0 -273
  914. package/src/plugins/shell/shell.test.ts +0 -314
  915. package/src/plugins/skills/discovery.test.ts +0 -395
  916. package/src/plugins/skills/skills.integration.test.ts +0 -580
  917. package/src/plugins/todo/todo.integration.test.ts +0 -687
  918. package/src/plugins/uploads/preprocessors/image-classifier.test.ts +0 -142
  919. package/src/plugins/uploads/uploads.integration.test.ts +0 -831
  920. package/src/plugins/user-chat/user-chat.integration.test.ts +0 -893
  921. package/src/plugins/workers/workers.integration.test.ts +0 -778
  922. package/src/prompts/macros.test.ts +0 -107
  923. package/src/testing/test-harness.test.ts +0 -114
  924. package/src/transport/http/routes/rpc.integration.test.ts +0 -243
  925. package/src/transport/http/routes/rpc.test.ts +0 -372
@@ -8,15 +8,19 @@
8
8
  */
9
9
  import { join } from 'node:path';
10
10
  import { COMMUNICATOR_ROLE, ORCHESTRATOR_ROLE } from '../../core/agents/agent-roles.js';
11
+ import { parseAgentWakeKey, parsePluginWakeKey } from '../../core/wake-key.js';
11
12
  import { generateAgentId } from '../../core/agents/schema.js';
12
13
  import { agentEvents } from '../../core/agents/state.js';
13
14
  import { PresetErrors, SessionErrors, ValidationErrors } from '../../core/errors.js';
14
15
  import { withSessionId } from '../../core/events/test-helpers.js';
16
+ import { DEFAULT_PLUGIN_ORDER } from '../../core/plugins/plugin-builder.js';
17
+ import { AGENT_CALLER } from '../../core/plugins/plugin-builder.js';
15
18
  import { knownDefinitionNames, unknownOverrideTargets } from '../../core/preset/overrides.js';
16
- import { generateSessionId } from '../../core/sessions/schema.js';
19
+ import { generateSessionId, isValidSessionId, SessionId } from '../../core/sessions/schema.js';
17
20
  import { checkRecoveryNeeded, isSessionCreatedEvent, reconstructSessionState, sessionEvents } from '../../core/sessions/state.js';
18
- import { FileLogger } from '../../lib/logger/file.js';
21
+ import { createSessionLogger } from '../../lib/logger/session-log.js';
19
22
  import { TeeLogger } from '../../lib/logger/tee.js';
23
+ import { isLiveScheduler } from '../../platform/index.js';
20
24
  import { Err, Ok } from '../../lib/utils/result.js';
21
25
  import { getAgentUnconsumedMailbox, selectMailboxState } from '../../plugins/mailbox/query.js';
22
26
  import { selectSessionStats } from '../../plugins/session-stats/index.js';
@@ -24,6 +28,7 @@ import { createApplyEvent } from './apply-event.js';
24
28
  import { rewriteEventsForFork } from './fork-utils.js';
25
29
  import { SessionStore } from './session-store.js';
26
30
  import { Session } from './session.js';
31
+ import { SessionRuntimeActivityController } from './runtime-activity.js';
27
32
  // ============================================================================
28
33
  // Errors
29
34
  // ============================================================================
@@ -39,13 +44,18 @@ class SessionLoadError extends Error {
39
44
  this.name = 'SessionLoadError';
40
45
  }
41
46
  }
47
+ // Both parking causes map to `evicted`: the session survives and the next access rebuilds its runtime.
48
+ const RUNTIME_DISPOSAL_CLOSE_REASON = {
49
+ idle: 'evicted',
50
+ disposed: 'evicted',
51
+ closed: 'closed',
52
+ shutdown: 'shutdown',
53
+ };
42
54
  /**
43
55
  * SessionManager manages session lifecycle and caching.
44
56
  */
45
57
  export class SessionManager {
46
58
  sessions = new Map();
47
- /** Unsubscribe functions for session event listeners, keyed by sessionId */
48
- sessionListenerCleanup = new Map();
49
59
  /** Manager-level methods collected from plugin definitions across all presets */
50
60
  managerMethods;
51
61
  eventStore;
@@ -58,12 +68,24 @@ export class SessionManager {
58
68
  dataFileStore;
59
69
  onUserOutput;
60
70
  preprocessorRegistry;
71
+ uploadArchiveLimits;
72
+ resourceArchiveLimits;
61
73
  llmLogger;
62
74
  portPool;
63
75
  pidRegistry;
64
76
  platform;
65
77
  systemPlugins;
78
+ sessionIdleTimeoutMs;
79
+ evictionSweepTimer;
80
+ cacheHits = 0;
81
+ cacheMisses = 0;
82
+ cacheEvictions = 0;
83
+ /** Set by shutdown(). Also fences wakes: one armed before it must not reload a session after it. */
84
+ shuttingDown = false;
66
85
  constructor(options) {
86
+ if (options.sessionIdleTimeoutMs !== undefined && (!Number.isSafeInteger(options.sessionIdleTimeoutMs) || options.sessionIdleTimeoutMs < 0)) {
87
+ throw new Error(`Invalid sessionIdleTimeoutMs: ${options.sessionIdleTimeoutMs}`);
88
+ }
67
89
  this.eventStore = options.eventStore;
68
90
  this.llmProvider = options.llmProvider;
69
91
  this.llmProviders = options.llmProviders ?? new Map();
@@ -74,21 +96,111 @@ export class SessionManager {
74
96
  this.dataFileStore = options.dataFileStore;
75
97
  this.onUserOutput = options.onUserOutput;
76
98
  this.preprocessorRegistry = options.preprocessorRegistry;
99
+ this.uploadArchiveLimits = options.uploadArchiveLimits;
100
+ this.resourceArchiveLimits = options.resourceArchiveLimits;
77
101
  this.llmLogger = options.llmLogger;
78
102
  this.portPool = options.portPool;
79
103
  this.pidRegistry = options.pidRegistry;
80
104
  this.platform = options.platform;
81
105
  this.systemPlugins = options.systemPlugins ?? [];
106
+ this.sessionIdleTimeoutMs = options.sessionIdleTimeoutMs ?? 0;
82
107
  this.managerMethods = this.collectManagerMethods();
108
+ if (this.sessionIdleTimeoutMs > 0) {
109
+ const sweepIntervalMs = Math.min(this.sessionIdleTimeoutMs, 60_000);
110
+ this.evictionSweepTimer = setInterval(() => {
111
+ void this.evictIdleSessions();
112
+ }, sweepIntervalMs);
113
+ this.evictionSweepTimer.unref();
114
+ }
115
+ // A live scheduler has nowhere else to deliver. Hosts that wake out-of-band
116
+ // (a Durable Object alarm) call dispatchWake() from their own handler.
117
+ const scheduler = this.platform.scheduler;
118
+ if (isLiveScheduler(scheduler)) {
119
+ scheduler.onWake(async (key) => {
120
+ try {
121
+ await this.dispatchWake(key);
122
+ }
123
+ catch (error) {
124
+ this.logger.error('Scheduler wake dispatch failed', error instanceof Error ? error : new Error(String(error)), { key });
125
+ }
126
+ });
127
+ }
83
128
  }
84
129
  /** Expose platform adapters (used by Session for building contexts). */
85
130
  getPlatform() {
86
131
  return this.platform;
87
132
  }
133
+ /**
134
+ * Deliver a scheduler wake that has come due.
135
+ *
136
+ * The host's entry point back into the SDK — on Cloudflare, called from
137
+ * `alarm()` in an isolate that never armed the wake. SessionManager owns it
138
+ * because it is the only thing that can turn a session id back into a live
139
+ * session, so the key alone is enough input.
140
+ *
141
+ * Two vocabularies route here: `agent:` wakes re-enter the agent loop,
142
+ * `plugin:` wakes call a plugin method. Anything else is a quiet no-op, and so
143
+ * is a key naming a session, agent or plugin that is gone — wakes outlive what
144
+ * they point at. Only genuinely unexpected failures (event store IO) throw, so
145
+ * a host that retries alarms retries those and only those.
146
+ */
147
+ async dispatchWake(key) {
148
+ const agentWake = parseAgentWakeKey(key);
149
+ if (agentWake) {
150
+ await this.withWakeTarget(key, agentWake.sessionId, async (session) => {
151
+ await session.getAgent(agentWake.agentId)?.deliverWake(agentWake.kind);
152
+ });
153
+ return;
154
+ }
155
+ const pluginWake = parsePluginWakeKey(key);
156
+ if (pluginWake) {
157
+ await this.withWakeTarget(key, pluginWake.sessionId, async (session) => {
158
+ const result = await session.callPluginMethod(`${pluginWake.pluginName}.${pluginWake.method}`, pluginWake.agentId === undefined ? {} : { agentId: pluginWake.agentId }, pluginWake.agentId, AGENT_CALLER);
159
+ // A preset that no longer registers the plugin lands here, same as a
160
+ // missing agent does: the wake points at something that is gone.
161
+ if (!result.ok)
162
+ this.logger.debug('Scheduler wake method rejected', { key, error: result.error.type });
163
+ });
164
+ return;
165
+ }
166
+ this.logger.debug('Ignoring unrecognized scheduler wake key', { key });
167
+ }
168
+ /** Run `deliver` against the session a due wake names, under a runtime lease. */
169
+ async withWakeTarget(key, sessionId, deliver) {
170
+ // Nothing armed before shutdown may load a session back in afterwards.
171
+ if (this.shuttingDown)
172
+ return;
173
+ // Nor may a wake that lands mid-teardown rebuild what is being torn down —
174
+ // getSession() would wait out the unload and reload. onSessionReady re-arms.
175
+ const resident = this.sessions.get(sessionId);
176
+ if (resident && (resident.state === 'evicting' || resident.activity.getSnapshot().state !== 'ready'))
177
+ return;
178
+ const sessionResult = await this.getSession(sessionId);
179
+ if (!sessionResult.ok) {
180
+ this.logger.debug('Scheduler wake for a session that no longer loads', { key, error: sessionResult.error.type });
181
+ return;
182
+ }
183
+ const session = sessionResult.value;
184
+ // A closed session's log is sealed; re-entering it would only fail to write.
185
+ if (session.state.status === 'closed')
186
+ return;
187
+ // Lease the delivery, not the delay before it — an idle session stays evictable while it waits.
188
+ const release = session.tryAcquireRuntimeLease(`wake:${key}`);
189
+ if (!release)
190
+ return;
191
+ try {
192
+ await deliver(session);
193
+ }
194
+ finally {
195
+ release();
196
+ }
197
+ }
88
198
  /**
89
199
  * Create a new session with the given preset.
90
200
  */
91
201
  async createSession(presetId, options) {
202
+ if (this.shuttingDown)
203
+ return Err(ValidationErrors.invalid('Session manager is shutting down'));
92
204
  const preset = this.presets.get(presetId);
93
205
  if (!preset) {
94
206
  return Err(PresetErrors.notFound(presetId));
@@ -99,7 +211,12 @@ export class SessionManager {
99
211
  return Err(ValidationErrors.invalid(`Unknown agent definitions in overrides: ${unknown.join(', ')}. Preset '${presetId}' defines: ${knownDefinitionNames(preset).join(', ')}`));
100
212
  }
101
213
  }
102
- const sessionId = options?.sessionId ? options.sessionId : generateSessionId();
214
+ // Validate before anything derives a path from it — the id reaches join() for the
215
+ // session dir, the event log and the file logger, and path.join collapses `..`.
216
+ if (options?.sessionId !== undefined && !isValidSessionId(options.sessionId)) {
217
+ return Err(ValidationErrors.invalid(`Invalid session id: ${JSON.stringify(options.sessionId)}`));
218
+ }
219
+ const sessionId = options?.sessionId ? SessionId(options.sessionId) : generateSessionId();
103
220
  // First orchestrator gets seq 1
104
221
  const orchestratorId = generateAgentId(ORCHESTRATOR_ROLE, 1);
105
222
  // Resolve workspaceDir: API input overrides preset default
@@ -145,21 +262,45 @@ export class SessionManager {
145
262
  orchestratorId,
146
263
  })));
147
264
  }
148
- // Write events to event store
149
- await this.eventStore.appendBatch(sessionId, events);
150
- // Build plugins and composed reducer so plugin state slices are applied
151
- const plugins = this.buildPlugins(preset);
152
- const composedReducer = createApplyEvent(plugins);
153
- // Reconstruct state with composed reducer (includes plugin state slices)
154
- const state = reconstructSessionState(events, composedReducer);
155
- if (!state) {
156
- return Err(ValidationErrors.invalid('Failed to reconstruct session'));
157
- }
158
- // Create store and session (initPluginContexts + onSessionReady hooks run inside)
159
- const store = new SessionStore(sessionId, this.eventStore, state, composedReducer);
160
- const session = await this.createSessionInstance(store, preset, plugins);
161
- // Cache session (wrap in resolved promise for consistency)
162
- this.sessions.set(sessionId, Promise.resolve(session));
265
+ if (this.sessions.has(sessionId))
266
+ return Err(SessionErrors.alreadyExists(String(sessionId)));
267
+ const activity = new SessionRuntimeActivityController();
268
+ let entry;
269
+ const creationPromise = Promise.resolve().then(async () => {
270
+ if (await this.eventStore.exists(sessionId))
271
+ throw new SessionLoadError(SessionErrors.alreadyExists(String(sessionId)));
272
+ await this.eventStore.appendBatch(sessionId, events);
273
+ const plugins = this.buildPlugins(preset);
274
+ const composedReducer = createApplyEvent(plugins);
275
+ const state = reconstructSessionState(events, composedReducer);
276
+ if (!state)
277
+ throw new SessionLoadError(ValidationErrors.invalid('Failed to reconstruct session'));
278
+ const store = new SessionStore(sessionId, this.eventStore, state, composedReducer);
279
+ return this.createSessionInstance(store, preset, plugins, entry);
280
+ });
281
+ entry = {
282
+ state: 'loading',
283
+ promise: creationPromise,
284
+ activity,
285
+ lastAccessAt: performance.now(),
286
+ };
287
+ this.sessions.set(sessionId, entry);
288
+ let session;
289
+ try {
290
+ session = await creationPromise;
291
+ if (this.sessions.get(sessionId) === entry && entry.state === 'loading') {
292
+ entry.state = 'ready';
293
+ entry.lastAccessAt = performance.now();
294
+ }
295
+ }
296
+ catch (error) {
297
+ if (this.sessions.get(sessionId) === entry)
298
+ this.sessions.delete(sessionId);
299
+ entry.listenerCleanup?.();
300
+ if (error instanceof SessionLoadError)
301
+ return Err(error.domainError);
302
+ throw error;
303
+ }
163
304
  this.logger.info('Session created', {
164
305
  sessionId,
165
306
  presetId,
@@ -172,8 +313,12 @@ export class SessionManager {
172
313
  * The forked session gets a copy of all events up to the fork point.
173
314
  */
174
315
  async forkSession(sourceSessionId, eventIndex) {
316
+ if (this.shuttingDown)
317
+ return Err(ValidationErrors.invalid('Session manager is shutting down'));
175
318
  // Load source events
176
319
  const sourceEvents = await this.eventStore.load(sourceSessionId);
320
+ if (this.shuttingDown)
321
+ return Err(ValidationErrors.invalid('Session manager is shutting down'));
177
322
  if (sourceEvents.length === 0) {
178
323
  return Err(SessionErrors.notFound(String(sourceSessionId)));
179
324
  }
@@ -210,32 +355,48 @@ export class SessionManager {
210
355
  return event;
211
356
  });
212
357
  }
213
- // Write forked events to event store
214
- await this.eventStore.appendBatch(newSessionId, forkedEvents);
215
- // Build plugins and composed reducer so plugin state slices are applied
216
- const plugins = this.buildPlugins(preset);
217
- const composedReducer = createApplyEvent(plugins);
218
- // Reconstruct state with composed reducer (includes plugin state slices)
219
- const state = reconstructSessionState(forkedEvents, composedReducer);
220
- if (!state) {
221
- return Err(ValidationErrors.invalid('Failed to reconstruct forked session'));
222
- }
223
- // Create store
224
- const store = new SessionStore(newSessionId, this.eventStore, state, composedReducer);
225
- // Normalize stuck agents via session_restarted event
226
- const recoveryData = checkRecoveryNeeded(state);
227
- if (recoveryData) {
228
- await store.emit(withSessionId(newSessionId, sessionEvents.create('session_restarted', {
229
- resetAgentIds: recoveryData.resetAgentIds,
230
- clearedToolAgentIds: recoveryData.clearedToolAgentIds,
231
- })));
358
+ const activity = new SessionRuntimeActivityController();
359
+ let entry;
360
+ const forkPromise = Promise.resolve().then(async () => {
361
+ await this.eventStore.appendBatch(newSessionId, forkedEvents);
362
+ const plugins = this.buildPlugins(preset);
363
+ const composedReducer = createApplyEvent(plugins);
364
+ const state = reconstructSessionState(forkedEvents, composedReducer);
365
+ if (!state)
366
+ throw new SessionLoadError(ValidationErrors.invalid('Failed to reconstruct forked session'));
367
+ const store = new SessionStore(newSessionId, this.eventStore, state, composedReducer);
368
+ const recoveryData = checkRecoveryNeeded(state);
369
+ if (recoveryData) {
370
+ await store.emit(withSessionId(newSessionId, sessionEvents.create('session_restarted', {
371
+ resetAgentIds: recoveryData.resetAgentIds,
372
+ clearedToolAgentIds: recoveryData.clearedToolAgentIds,
373
+ })));
374
+ }
375
+ return this.createSessionInstance(store, preset, plugins, entry);
376
+ });
377
+ entry = {
378
+ state: 'loading',
379
+ promise: forkPromise,
380
+ activity,
381
+ lastAccessAt: performance.now(),
382
+ };
383
+ this.sessions.set(newSessionId, entry);
384
+ let session;
385
+ try {
386
+ session = await forkPromise;
387
+ if (this.sessions.get(newSessionId) === entry && entry.state === 'loading')
388
+ entry.state = 'ready';
389
+ }
390
+ catch (error) {
391
+ if (this.sessions.get(newSessionId) === entry)
392
+ this.sessions.delete(newSessionId);
393
+ entry.listenerCleanup?.();
394
+ if (error instanceof SessionLoadError)
395
+ return Err(error.domainError);
396
+ throw error;
232
397
  }
233
- // Create session instance (auto-start services run via onSessionReady)
234
- const session = await this.createSessionInstance(store, preset, plugins);
235
398
  // Check for pending agents
236
399
  session.checkPendingAgents();
237
- // Cache session
238
- this.sessions.set(newSessionId, Promise.resolve(session));
239
400
  this.logger.info('Session forked', {
240
401
  sourceSessionId,
241
402
  newSessionId,
@@ -247,39 +408,62 @@ export class SessionManager {
247
408
  * Get a session by ID - from cache or load from event store.
248
409
  */
249
410
  async getSession(sessionId) {
250
- // Check cache first
251
- const cached = this.sessions.get(sessionId);
252
- if (cached) {
411
+ while (true) {
412
+ if (this.shuttingDown)
413
+ return Err(ValidationErrors.invalid('Session manager is shutting down'));
414
+ let entry = this.sessions.get(sessionId);
415
+ if (entry?.state === 'evicting') {
416
+ await entry.unloadPromise;
417
+ continue;
418
+ }
419
+ if (entry?.state === 'ready' && entry.activity.getSnapshot().state !== 'ready') {
420
+ const session = await entry.promise;
421
+ await this.beginCacheEntryDisposal(sessionId, entry, session, 'disposed');
422
+ continue;
423
+ }
424
+ if (entry) {
425
+ this.cacheHits++;
426
+ entry.lastAccessAt = performance.now();
427
+ }
428
+ else {
429
+ this.cacheMisses++;
430
+ const activity = new SessionRuntimeActivityController();
431
+ let loadingEntry;
432
+ const promise = Promise.resolve().then(() => this.loadSession(sessionId, loadingEntry));
433
+ loadingEntry = {
434
+ state: 'loading',
435
+ activity,
436
+ lastAccessAt: performance.now(),
437
+ promise,
438
+ };
439
+ entry = loadingEntry;
440
+ this.sessions.set(sessionId, entry);
441
+ }
253
442
  try {
254
- return Ok(await cached);
443
+ const session = await entry.promise;
444
+ if (this.sessions.get(sessionId) === entry && entry.state === 'loading') {
445
+ if (session.state.status === 'closed')
446
+ this.sessions.delete(sessionId);
447
+ else {
448
+ entry.state = 'ready';
449
+ entry.lastAccessAt = performance.now();
450
+ }
451
+ }
452
+ return Ok(session);
255
453
  }
256
454
  catch (error) {
257
- // Previous load failed, remove from cache and try again
258
- this.sessions.delete(sessionId);
259
- if (error instanceof SessionLoadError) {
455
+ if (this.sessions.get(sessionId) === entry)
456
+ this.sessions.delete(sessionId);
457
+ if (error instanceof SessionLoadError)
260
458
  return Err(error.domainError);
261
- }
262
459
  throw error;
263
460
  }
264
461
  }
265
- // Store promise immediately to prevent concurrent loads
266
- const loadPromise = this.loadSession(sessionId);
267
- this.sessions.set(sessionId, loadPromise);
268
- try {
269
- return Ok(await loadPromise);
270
- }
271
- catch (error) {
272
- this.sessions.delete(sessionId);
273
- if (error instanceof SessionLoadError) {
274
- return Err(error.domainError);
275
- }
276
- throw error;
277
- }
278
462
  }
279
463
  /**
280
464
  * Internal session loading - throws SessionLoadError on domain errors.
281
465
  */
282
- async loadSession(sessionId) {
466
+ async loadSession(sessionId, entry) {
283
467
  // We need to peek at events first to determine the preset, so we can build plugins
284
468
  // and compose the reducer before loading the store
285
469
  const events = await this.eventStore.load(sessionId);
@@ -298,18 +482,16 @@ export class SessionManager {
298
482
  const plugins = this.buildPlugins(preset);
299
483
  const composedReducer = createApplyEvent(plugins);
300
484
  // Load store with composed reducer
301
- const store = await SessionStore.load(sessionId, this.eventStore, composedReducer);
485
+ const store = await SessionStore.fromEvents(sessionId, this.eventStore, events, composedReducer);
302
486
  if (!store) {
303
487
  throw new SessionLoadError(SessionErrors.notFound(String(sessionId)));
304
488
  }
305
489
  const state = store.getState();
306
490
  // Don't cache closed sessions
307
491
  if (state.status === 'closed') {
308
- // Remove from cache since we don't cache closed sessions
309
- this.sessions.delete(sessionId);
310
492
  // Skip onSessionReady hooks — closed sessions are immutable, firing hooks
311
493
  // would emit events to a sealed event log on every read / restart.
312
- return await this.createSessionInstance(store, preset, plugins, { skipReadyHooks: true });
494
+ return await this.createSessionInstance(store, preset, plugins, entry, { skipReadyHooks: true });
313
495
  }
314
496
  // Check if recovery is needed after restart
315
497
  const recoveryData = checkRecoveryNeeded(state);
@@ -325,7 +507,7 @@ export class SessionManager {
325
507
  });
326
508
  }
327
509
  // Create session (auto-start services run via onSessionReady)
328
- const session = await this.createSessionInstance(store, preset, plugins);
510
+ const session = await this.createSessionInstance(store, preset, plugins, entry);
329
511
  // Check for pending agents
330
512
  session.checkPendingAgents();
331
513
  return session;
@@ -338,10 +520,48 @@ export class SessionManager {
338
520
  * @param agentId - Agent ID (optional — some methods don't operate on a specific agent)
339
521
  */
340
522
  async callPluginMethod(sessionId, method, input, agentId, caller) {
341
- const sessionResult = await this.getSession(sessionId);
342
- if (!sessionResult.ok)
343
- return sessionResult;
344
- return sessionResult.value.callPluginMethod(method, input, agentId, caller);
523
+ return this.withSessionLease(sessionId, `request:${method}`, (session) => (session.callPluginMethod(method, input, agentId, caller)));
524
+ }
525
+ /** Run an operation while atomically keeping the selected runtime resident. */
526
+ async withSessionLease(sessionId, reason, operation) {
527
+ const acquired = await this.acquireSessionLease(sessionId, reason);
528
+ if (!acquired.ok)
529
+ return acquired;
530
+ try {
531
+ return await operation(acquired.value.session);
532
+ }
533
+ finally {
534
+ acquired.value.release();
535
+ }
536
+ }
537
+ /** Atomically look up a runtime and acquire a caller-managed lease on it. */
538
+ async acquireSessionLease(sessionId, reason) {
539
+ while (true) {
540
+ const sessionResult = await this.getSession(sessionId);
541
+ if (!sessionResult.ok)
542
+ return sessionResult;
543
+ const entry = this.sessions.get(sessionId);
544
+ if (!entry)
545
+ return Ok({ session: sessionResult.value, release: () => { } });
546
+ const release = entry.activity.tryAcquire(reason);
547
+ if (!release) {
548
+ if (entry.unloadPromise)
549
+ await entry.unloadPromise;
550
+ continue;
551
+ }
552
+ entry.lastAccessAt = performance.now();
553
+ let released = false;
554
+ return Ok({
555
+ session: sessionResult.value,
556
+ release: () => {
557
+ if (released)
558
+ return;
559
+ released = true;
560
+ entry.lastAccessAt = performance.now();
561
+ release();
562
+ },
563
+ });
564
+ }
345
565
  }
346
566
  /**
347
567
  * Call a manager-level plugin method.
@@ -415,14 +635,16 @@ export class SessionManager {
415
635
  let pendingAgents = 0;
416
636
  let processingAgents = 0;
417
637
  let lastActivityAt = null;
418
- // Wait for all sessions, ignoring failures
419
- const sessions = await Promise.all(Array.from(this.sessions.values()).map((p) => p.catch(() => null)));
638
+ const metadataResult = await this.eventStore.listSessionsWithMetadata();
639
+ const openMetadata = metadataResult.sessions.filter((metadata) => metadata.status !== 'closed');
640
+ // Wait for resident sessions, ignoring failed and evicting loads.
641
+ const sessions = await Promise.all(Array.from(this.sessions.values())
642
+ .filter((entry) => entry.state !== 'evicting')
643
+ .map((entry) => entry.promise.catch(() => null)));
420
644
  // Filter out closed sessions — they do not contribute to activity
421
645
  const openSessions = sessions.filter((s) => s !== null && s.state.status !== 'closed');
422
- // Fetch metadata only for open sessions
423
- const metadataResults = await Promise.all(openSessions.map((s) => this.eventStore.getMetadata(s.state.id).catch(() => null)));
424
- for (const metadata of metadataResults) {
425
- if (metadata?.lastActivityAt) {
646
+ for (const metadata of openMetadata) {
647
+ if (metadata.lastActivityAt) {
426
648
  if (lastActivityAt === null
427
649
  || metadata.lastActivityAt > lastActivityAt) {
428
650
  lastActivityAt = metadata.lastActivityAt;
@@ -430,6 +652,7 @@ export class SessionManager {
430
652
  }
431
653
  }
432
654
  const sessionStats = [];
655
+ const loadedById = new Map(openSessions.map((session) => [session.id, session]));
433
656
  for (const session of openSessions) {
434
657
  for (const [agentId, agentState] of session.state.agents) {
435
658
  if (agentState.status === 'pending') {
@@ -443,15 +666,19 @@ export class SessionManager {
443
666
  processingAgents++;
444
667
  }
445
668
  }
669
+ }
670
+ for (const metadata of openMetadata) {
671
+ const loaded = loadedById.get(metadata.sessionId);
446
672
  sessionStats.push({
447
- id: session.state.id,
448
- presetId: session.state.presetId,
449
- status: session.state.status,
450
- metrics: selectSessionStats(session.state),
673
+ id: metadata.sessionId,
674
+ presetId: metadata.presetId,
675
+ status: loaded?.state.status ?? metadata.status,
676
+ metrics: loaded ? selectSessionStats(loaded.state) : statsFromMetadata(metadata),
451
677
  });
452
678
  }
453
679
  return {
454
- sessionCount: openSessions.length,
680
+ sessionCount: openMetadata.length,
681
+ loadedSessionCount: openSessions.length,
455
682
  pendingAgents,
456
683
  processingAgents,
457
684
  lastActivityAt,
@@ -462,31 +689,75 @@ export class SessionManager {
462
689
  * Shutdown - clean up all sessions.
463
690
  */
464
691
  async shutdown() {
465
- // Wait for all sessions, ignoring failures
466
- const sessions = await Promise.all(Array.from(this.sessions.values()).map((p) => p.catch(() => null)));
467
- for (const session of sessions) {
468
- if (session) {
469
- session.shutdown();
692
+ this.shuttingDown = true;
693
+ if (this.evictionSweepTimer)
694
+ clearInterval(this.evictionSweepTimer);
695
+ await Promise.all([...this.sessions].map(async ([sessionId, entry]) => {
696
+ try {
697
+ const session = await entry.promise;
698
+ await this.beginCacheEntryDisposal(sessionId, entry, session, 'shutdown');
470
699
  }
471
- }
700
+ catch (error) {
701
+ entry.listenerCleanup?.();
702
+ entry.listenerCleanup = undefined;
703
+ this.logger.error('Failed to dispose session during shutdown', error instanceof Error ? error : new Error(String(error)), { sessionId });
704
+ }
705
+ }));
472
706
  this.sessions.clear();
473
- for (const cleanup of this.sessionListenerCleanup.values()) {
474
- cleanup();
475
- }
476
- this.sessionListenerCleanup.clear();
477
707
  this.logger.info('SessionManager shutdown complete');
478
708
  }
709
+ /** Narrow runtime-cache diagnostics for lifecycle tests and operational logs. */
710
+ getRuntimeCacheStats() {
711
+ return {
712
+ hits: this.cacheHits,
713
+ misses: this.cacheMisses,
714
+ evictions: this.cacheEvictions,
715
+ loadedSessionCount: this.sessions.size,
716
+ sessions: [...this.sessions].map(([id, entry]) => {
717
+ const activity = entry.activity.getSnapshot();
718
+ return {
719
+ id,
720
+ state: entry.state,
721
+ lastAccessAt: Math.max(entry.lastAccessAt, activity.lastActivityAt),
722
+ activeLeaseCount: activity.activeCount,
723
+ leaseReasons: activity.reasons,
724
+ };
725
+ }),
726
+ };
727
+ }
728
+ /**
729
+ * Sessions whose runtime is already resident and ready.
730
+ *
731
+ * Deliberately does not load, and does not refresh `lastAccessAt` — a passive
732
+ * reader must not keep a runtime alive or resurrect an evicted one. Use this
733
+ * over `getSession()` for read-only sweeps across sessions.
734
+ */
735
+ async listResidentSessions() {
736
+ const entries = [...this.sessions].filter(([, entry]) => entry.state === 'ready');
737
+ const sessions = await Promise.all(entries.map(async ([sessionId, entry]) => {
738
+ const session = await entry.promise.catch(() => null);
739
+ // Re-check: the entry can start evicting while we await the resolved promise.
740
+ if (!session || this.sessions.get(sessionId) !== entry || entry.state !== 'ready')
741
+ return null;
742
+ return session;
743
+ }));
744
+ return sessions.filter((session) => session !== null);
745
+ }
479
746
  // ============================================================================
480
747
  // Private methods
481
748
  // ============================================================================
482
749
  /**
483
- * Build ConfiguredPlugin[] for a session.
750
+ * Build ConfiguredPlugin[] for a session, in hook order.
484
751
  *
485
752
  * Iterates all system-registered plugins. For each:
486
753
  * 1. Check if preset has explicit SessionPluginConfig → use that config
487
754
  * 2. If not, try auto-deriving infrastructure config (agents, uploads, services)
488
755
  * 3. If no config at all → call .create() with no args (void config)
489
756
  * 4. Check isSessionEnabled — skip plugin if not enabled
757
+ *
758
+ * The result is sorted by each plugin's declared `.order()` — the precedence
759
+ * between plugins that both want the same hook, since most agent hooks stop
760
+ * at the first non-null result.
490
761
  */
491
762
  buildPlugins(preset) {
492
763
  // Build a lookup from preset Sessionplugins
@@ -546,7 +817,8 @@ export class SessionManager {
546
817
  }
547
818
  }
548
819
  }
549
- return plugins;
820
+ // Stable, so plugins that declare no order keep their registration order.
821
+ return plugins.sort((a, b) => (a.order ?? DEFAULT_PLUGIN_ORDER) - (b.order ?? DEFAULT_PLUGIN_ORDER));
550
822
  }
551
823
  /**
552
824
  * Build infrastructure-derived plugin configs from preset data.
@@ -569,7 +841,11 @@ export class SessionManager {
569
841
  configs.set('uploads', {
570
842
  dataFileStore: this.dataFileStore,
571
843
  preprocessorRegistry: this.preprocessorRegistry,
844
+ archiveLimits: this.uploadArchiveLimits,
572
845
  });
846
+ if (this.resourceArchiveLimits) {
847
+ configs.set('resources', { archiveLimits: this.resourceArchiveLimits });
848
+ }
573
849
  // services plugin — collect services from all agent definitions
574
850
  const allAgentConfigs = [preset.orchestrator, ...(preset.communicator ? [preset.communicator] : []), ...preset.agents];
575
851
  const servicesByType = new Map();
@@ -592,15 +868,11 @@ export class SessionManager {
592
868
  * which must remain immutable: running hooks would emit session_handler_* events
593
869
  * to a sealed event log on every introspection / restart cycle.
594
870
  */
595
- async createSessionInstance(store, preset, plugins, opts = {}) {
596
- // Only register cache eviction listener for active sessions (not closed)
597
- if (store.getState().status !== 'closed') {
598
- this.registerSessionEventListener(store.sessionId, store);
599
- }
871
+ async createSessionInstance(store, preset, plugins, entry, opts = {}) {
600
872
  const sessionDir = this.getSessionDir(store.sessionId);
601
873
  const sessionLogger = new TeeLogger([
602
874
  this.logger.child({ sessionId: store.sessionId }),
603
- new FileLogger(join(sessionDir, 'session.log'), this.platform.fs, { sessionId: String(store.sessionId) }),
875
+ createSessionLogger(this.platform, String(store.sessionId), join(sessionDir, 'session.log')),
604
876
  ]);
605
877
  // Create session
606
878
  const session = new Session({
@@ -616,20 +888,31 @@ export class SessionManager {
616
888
  eventStore: this.eventStore,
617
889
  llmLogger: this.llmLogger,
618
890
  platform: this.platform,
891
+ runtimeActivity: entry.activity,
892
+ registerReopenedSession: (reopenedSession) => this.registerReopenedSession(reopenedSession, entry.activity),
619
893
  });
894
+ // Only register cache eviction listener for active sessions (not closed)
895
+ if (store.getState().status !== 'closed') {
896
+ this.registerSessionEventListener(store.sessionId, store, session, entry);
897
+ }
620
898
  // Ensure session and workspace directories exist before plugins run
621
899
  await this.platform.fs.mkdir(sessionDir, { recursive: true });
622
900
  const workspaceDir = store.getState().workspaceDir;
623
901
  if (workspaceDir) {
624
902
  await this.platform.fs.mkdir(workspaceDir, { recursive: true });
625
903
  }
626
- // Initialize plugin contexts (calls createContext for each plugin).
627
- // Safe for closed sessions — createContext is pure local setup, no event emit.
628
- await session.initPluginContexts();
629
- // Call onSessionReady hooks with full context.
630
- // Skipped for closed sessions to preserve event log immutability.
631
- if (!opts.skipReadyHooks) {
632
- await session.callSessionReadyHooks();
904
+ try {
905
+ // Safe for closed sessions — createContext is pure local setup, no event emit.
906
+ await session.initPluginContexts();
907
+ // Skipped for closed sessions to preserve event log immutability.
908
+ if (!opts.skipReadyHooks)
909
+ await session.callSessionReadyHooks();
910
+ }
911
+ catch (error) {
912
+ await session.dispose('evicted');
913
+ entry.listenerCleanup?.();
914
+ entry.listenerCleanup = undefined;
915
+ throw error;
633
916
  }
634
917
  return session;
635
918
  }
@@ -653,20 +936,136 @@ export class SessionManager {
653
936
  * Cleans up any previous listener for this sessionId (from a prior load)
654
937
  * to prevent duplicate listeners firing on old stores.
655
938
  */
656
- registerSessionEventListener(sessionId, store) {
657
- const prevCleanup = this.sessionListenerCleanup.get(sessionId);
658
- if (prevCleanup)
659
- prevCleanup();
939
+ registerSessionEventListener(sessionId, store, session, entry) {
940
+ entry.listenerCleanup?.();
660
941
  const unsubscribe = store.onEvent((event) => {
661
- if (event.type === 'session_closed' || event.type === 'session_reopened') {
662
- this.sessions.delete(sessionId);
663
- this.sessionListenerCleanup.delete(sessionId);
942
+ if (event.type === 'session_closed') {
943
+ if (this.sessions.get(sessionId) === entry)
944
+ this.beginCacheEntryDisposal(sessionId, entry, session, 'closed');
945
+ else
946
+ void session.dispose('closed');
947
+ }
948
+ else if (event.type === 'session_reopened') {
949
+ if (this.sessions.get(sessionId) === entry)
950
+ this.sessions.delete(sessionId);
951
+ unsubscribe();
952
+ entry.listenerCleanup = undefined;
664
953
  }
665
954
  });
666
- this.sessionListenerCleanup.set(sessionId, unsubscribe);
955
+ entry.listenerCleanup = unsubscribe;
956
+ }
957
+ registerReopenedSession(session, activity) {
958
+ if (this.shuttingDown)
959
+ return Err(ValidationErrors.invalid('Session manager is shutting down'));
960
+ if (activity.getSnapshot().state !== 'ready')
961
+ return Ok(undefined);
962
+ if (this.sessions.has(session.id))
963
+ return Err(SessionErrors.alreadyExists(String(session.id)));
964
+ const deferred = Promise.withResolvers();
965
+ void deferred.promise.catch(() => { });
966
+ const entry = {
967
+ state: 'loading',
968
+ promise: deferred.promise,
969
+ activity,
970
+ lastAccessAt: performance.now(),
971
+ };
972
+ this.sessions.set(session.id, entry);
973
+ return Ok({
974
+ complete: async () => {
975
+ if (this.sessions.get(session.id) !== entry) {
976
+ throw new Error(`Reopened session lost cache ownership: ${session.id}`);
977
+ }
978
+ this.registerSessionEventListener(session.id, session.store, session, entry);
979
+ try {
980
+ await session.callSessionReadyHooks();
981
+ session.checkPendingAgents();
982
+ if (this.sessions.get(session.id) !== entry || entry.state !== 'loading' || activity.getSnapshot().state !== 'ready') {
983
+ throw new Error(`Reopened session became unavailable during ready hooks: ${session.id}`);
984
+ }
985
+ entry.state = 'ready';
986
+ entry.lastAccessAt = performance.now();
987
+ deferred.resolve(session);
988
+ }
989
+ catch (error) {
990
+ if (this.sessions.get(session.id) === entry)
991
+ this.sessions.delete(session.id);
992
+ entry.listenerCleanup?.();
993
+ entry.listenerCleanup = undefined;
994
+ deferred.reject(error);
995
+ await session.dispose('evicted');
996
+ throw error;
997
+ }
998
+ },
999
+ abort: (error) => {
1000
+ if (this.sessions.get(session.id) === entry)
1001
+ this.sessions.delete(session.id);
1002
+ entry.listenerCleanup?.();
1003
+ entry.listenerCleanup = undefined;
1004
+ deferred.reject(error);
1005
+ },
1006
+ });
1007
+ }
1008
+ async evictIdleSessions() {
1009
+ if (this.sessionIdleTimeoutMs === 0)
1010
+ return;
1011
+ const now = performance.now();
1012
+ const disposals = [];
1013
+ for (const [sessionId, entry] of this.sessions) {
1014
+ if (entry.state !== 'ready')
1015
+ continue;
1016
+ const activity = entry.activity.getSnapshot();
1017
+ if (now - Math.max(entry.lastAccessAt, activity.lastActivityAt) < this.sessionIdleTimeoutMs)
1018
+ continue;
1019
+ if (!entry.activity.tryBeginUnload())
1020
+ continue;
1021
+ const session = await entry.promise;
1022
+ disposals.push(this.beginCacheEntryDisposal(sessionId, entry, session, 'idle'));
1023
+ }
1024
+ await Promise.all(disposals);
1025
+ }
1026
+ beginCacheEntryDisposal(sessionId, entry, session, reason) {
1027
+ if (entry.unloadPromise)
1028
+ return entry.unloadPromise;
1029
+ entry.state = 'evicting';
1030
+ entry.activity.beginForcedUnload();
1031
+ entry.unloadPromise = session.dispose(RUNTIME_DISPOSAL_CLOSE_REASON[reason])
1032
+ .catch((error) => {
1033
+ this.logger.error('Failed to dispose session runtime', error instanceof Error ? error : new Error(String(error)), { sessionId, reason });
1034
+ })
1035
+ .finally(() => {
1036
+ if (this.sessions.get(sessionId) === entry)
1037
+ this.sessions.delete(sessionId);
1038
+ entry.listenerCleanup?.();
1039
+ entry.listenerCleanup = undefined;
1040
+ if (reason === 'idle')
1041
+ this.cacheEvictions++;
1042
+ this.logger.debug('Session runtime evicted', { sessionId, reason });
1043
+ });
1044
+ return entry.unloadPromise;
667
1045
  }
668
1046
  getSessionDir(sessionId) {
669
1047
  return join(this.basePath, 'sessions', String(sessionId));
670
1048
  }
671
1049
  }
1050
+ function statsFromMetadata(metadata) {
1051
+ return {
1052
+ totalTokens: metadata.metrics?.totalTokens ?? 0,
1053
+ promptTokens: metadata.metrics?.inputTokens ?? 0,
1054
+ completionTokens: metadata.metrics?.outputTokens ?? 0,
1055
+ cacheReadTokens: 0,
1056
+ cacheWriteTokens: 0,
1057
+ totalCost: metadata.metrics?.totalCost ?? 0,
1058
+ llmCalls: metadata.metrics?.totalLLMCalls ?? 0,
1059
+ llmErrors: 0,
1060
+ toolCalls: metadata.metrics?.totalToolCalls ?? 0,
1061
+ toolErrors: 0,
1062
+ userMessages: metadata.metrics?.totalMessages ?? 0,
1063
+ compactions: 0,
1064
+ agentCount: metadata.metrics?.totalAgents ?? 0,
1065
+ firstEventAt: metadata.createdAt,
1066
+ lastEventAt: metadata.lastActivityAt,
1067
+ byProvider: {},
1068
+ byAgent: {},
1069
+ };
1070
+ }
672
1071
  //# sourceMappingURL=session-manager.js.map