@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
@@ -1,887 +0,0 @@
1
- import { describe, expect, it } from 'bun:test';
2
- import z from 'zod/v4';
3
- import { AgentId } from '../../core/agents/schema.js';
4
- import { agentEvents } from '../../core/agents/state.js';
5
- import { MockLLMProvider } from '../../core/llm/mock.js';
6
- import { ModelId } from '../../core/llm/schema.js';
7
- import { llmEvents } from '../../core/llm/state.js';
8
- import { selectPluginState } from '../../core/sessions/reducer.js';
9
- import { createTool } from '../../core/tools/definition.js';
10
- import { ToolCallId } from '../../core/tools/schema.js';
11
- import { toolEvents } from '../../core/tools/state.js';
12
- import { Ok } from '../../lib/utils/result.js';
13
- import { contextCompactPlugin } from '../../plugins/context-compact/index.js';
14
- import { getAgentMailbox, selectMailboxState } from '../../plugins/mailbox/query.js';
15
- import { mailboxEvents } from '../../plugins/mailbox/state.js';
16
- import { createMultiAgentPreset, createTestPreset, TestHarness } from '../../testing/index.js';
17
- import { limitsEvents, limitsGuardPlugin } from './plugin.js';
18
- function createLimitsHarness(options) {
19
- return new TestHarness({ ...options, systemPlugins: [limitsGuardPlugin] });
20
- }
21
- /**
22
- * Wait for a specific agent to reach 'paused' status (or timeout).
23
- * Polls the TestSession's state directly (live getter).
24
- */
25
- async function waitForAgentPaused(session, agentId, timeoutMs = 10000) {
26
- const deadline = Date.now() + timeoutMs;
27
- while (Date.now() < deadline) {
28
- const agentState = session.state.agents.get(agentId);
29
- if (agentState?.status === 'paused')
30
- return;
31
- await new Promise(r => setTimeout(r, 10));
32
- }
33
- throw new Error(`waitForAgentPaused timed out after ${timeoutMs}ms for agent ${agentId}`);
34
- }
35
- async function waitUntil(predicate, timeoutMs = 10000) {
36
- const deadline = Date.now() + timeoutMs;
37
- while (Date.now() < deadline) {
38
- if (predicate())
39
- return;
40
- await new Promise((resolve) => setTimeout(resolve, 10));
41
- }
42
- throw new Error(`waitUntil timed out after ${timeoutMs}ms`);
43
- }
44
- /**
45
- * Wait for all agents to be either idle (pending with no work) or paused.
46
- */
47
- async function waitForAllSettled(session, timeoutMs = 10000) {
48
- const deadline = Date.now() + timeoutMs;
49
- outer: while (Date.now() < deadline) {
50
- for (const [, agentState] of session.state.agents) {
51
- if (agentState.status === 'paused')
52
- continue;
53
- if (agentState.status === 'pending' && agentState.pendingToolCalls.length === 0 && agentState.pendingToolResults.length === 0) {
54
- continue;
55
- }
56
- await new Promise(r => setTimeout(r, 10));
57
- continue outer;
58
- }
59
- // Double-check after a brief delay
60
- await new Promise(r => setTimeout(r, 10));
61
- for (const [, agentState] of session.state.agents) {
62
- if (agentState.status === 'paused')
63
- continue;
64
- if (agentState.status === 'pending' && agentState.pendingToolCalls.length === 0 && agentState.pendingToolResults.length === 0) {
65
- continue;
66
- }
67
- continue outer;
68
- }
69
- return;
70
- }
71
- throw new Error(`waitForAllSettled timed out after ${timeoutMs}ms`);
72
- }
73
- describe('limits-guard plugin', () => {
74
- // =========================================================================
75
- // hard limits
76
- // =========================================================================
77
- describe('hard limits', () => {
78
- it('agent exceeding inference hard limit → agent_paused event → agent stops', async () => {
79
- let inferenceCount = 0;
80
- const harness = createLimitsHarness({
81
- presets: [createTestPreset({
82
- orchestratorSystem: 'Test agent.',
83
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxTurns: 3 } })],
84
- })],
85
- mockHandler: () => {
86
- inferenceCount++;
87
- return {
88
- content: null,
89
- toolCalls: [{ id: ToolCallId(`tc${inferenceCount}`), name: 'tell_user', input: { message: `Turn ${inferenceCount}` } }],
90
- finishReason: 'stop',
91
- metrics: MockLLMProvider.defaultMetrics(),
92
- };
93
- },
94
- });
95
- const session = await harness.createSession('test');
96
- const entryAgentId = session.getEntryAgentId();
97
- await session.sendMessage('Start');
98
- await waitForAgentPaused(session, entryAgentId);
99
- const entryAgent = session.state.agents.get(entryAgentId);
100
- expect(entryAgent.status).toBe('paused');
101
- const pausedEvents = await session.getEventsByType(agentEvents, 'agent_paused');
102
- expect(pausedEvents.length).toBeGreaterThanOrEqual(1);
103
- const pauseEvent = pausedEvents.find(e => e.agentId === entryAgentId);
104
- expect(pauseEvent).toBeDefined();
105
- expect(pauseEvent.reason).toBe('handler');
106
- await harness.shutdown();
107
- });
108
- it('agent exceeding tool call hard limit → agent paused', async () => {
109
- let callNum = 0;
110
- const harness = createLimitsHarness({
111
- presets: [createTestPreset({
112
- orchestratorSystem: 'Test agent.',
113
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxToolCalls: 3, maxTurns: 100 } })],
114
- })],
115
- mockHandler: () => {
116
- callNum++;
117
- return {
118
- content: null,
119
- toolCalls: [
120
- { id: ToolCallId(`tc${callNum}a`), name: 'tell_user', input: { message: `A${callNum}` } },
121
- { id: ToolCallId(`tc${callNum}b`), name: 'tell_user', input: { message: `B${callNum}` } },
122
- ],
123
- finishReason: 'stop',
124
- metrics: MockLLMProvider.defaultMetrics(),
125
- };
126
- },
127
- });
128
- const session = await harness.createSession('test');
129
- const entryAgentId = session.getEntryAgentId();
130
- await session.sendMessage('Start');
131
- await waitForAgentPaused(session, entryAgentId);
132
- const entryAgent = session.state.agents.get(entryAgentId);
133
- expect(entryAgent.status).toBe('paused');
134
- const counters = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
135
- expect(counters).toBeDefined();
136
- expect(counters.toolCallCount).toBeGreaterThanOrEqual(3);
137
- await harness.shutdown();
138
- });
139
- it('agent exceeding spawned agent limit → agent paused', async () => {
140
- let orchestratorCalls = 0;
141
- const harness = createLimitsHarness({
142
- presets: [createMultiAgentPreset([
143
- { name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
144
- ], { orchestratorSystem: 'Orchestrator agent.' })],
145
- mockHandler: (request) => {
146
- if (request.systemPrompt.includes('Orchestrator')) {
147
- orchestratorCalls++;
148
- return {
149
- content: null,
150
- toolCalls: [
151
- { id: ToolCallId(`tc${orchestratorCalls}a`), name: 'start_worker', input: { message: `Task ${orchestratorCalls}a` } },
152
- { id: ToolCallId(`tc${orchestratorCalls}b`), name: 'start_worker', input: { message: `Task ${orchestratorCalls}b` } },
153
- ],
154
- finishReason: 'stop',
155
- metrics: MockLLMProvider.defaultMetrics(),
156
- };
157
- }
158
- return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
159
- },
160
- });
161
- const session = await harness.createSession('test');
162
- const orchestratorId = session.getEntryAgentId();
163
- await session.sendMessage('Start');
164
- await waitForAgentPaused(session, orchestratorId, 15000);
165
- const orch = session.state.agents.get(orchestratorId);
166
- expect(orch.status).toBe('paused');
167
- const counters = selectPluginState(session.state, 'agentLimits')?.get(orchestratorId);
168
- expect(counters).toBeDefined();
169
- expect(counters.spawnedAgentCount).toBeGreaterThanOrEqual(10);
170
- await harness.shutdown();
171
- });
172
- it('communication-only loop without new inbound work → soft-stops and remains wakeable', async () => {
173
- let inferenceCount = 0;
174
- const harness = createLimitsHarness({
175
- presets: [createTestPreset({
176
- orchestratorSystem: 'Test agent.',
177
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({
178
- limits: { maxConsecutiveNoProgressTurns: 3, maxTurns: 100 },
179
- })],
180
- })],
181
- mockHandler: () => {
182
- inferenceCount++;
183
- if (inferenceCount > 4) {
184
- return {
185
- content: 'Recovered for new work',
186
- toolCalls: [],
187
- finishReason: 'stop',
188
- metrics: MockLLMProvider.defaultMetrics(),
189
- };
190
- }
191
- return {
192
- content: null,
193
- toolCalls: [{
194
- id: ToolCallId(`tc${inferenceCount}`),
195
- name: 'tell_user',
196
- input: { message: `Still waiting, update ${inferenceCount}` },
197
- }],
198
- finishReason: 'stop',
199
- metrics: MockLLMProvider.defaultMetrics(),
200
- };
201
- },
202
- });
203
- const session = await harness.createSession('test');
204
- const entryAgentId = session.getEntryAgentId();
205
- await session.sendAndWaitForIdle('Start');
206
- // The response to "Start" had inbound work. The next three turns were
207
- // driven only by the previous tell_user result, so the fourth inference
208
- // reaches the limit and its redundant tool call is suppressed.
209
- expect(inferenceCount).toBe(4);
210
- const toolStarted = await session.getEventsByType(toolEvents, 'tool_started');
211
- expect(toolStarted).toHaveLength(3);
212
- const pauseEvents = await session.getEventsByType(agentEvents, 'agent_paused');
213
- expect(pauseEvents.some((event) => event.agentId === entryAgentId)).toBe(false);
214
- const warningEvents = await session.getEventsByType(limitsEvents, 'limit_warning');
215
- const noProgressEvent = warningEvents.find((event) => event.agentId === entryAgentId
216
- && event.limitName === 'maxConsecutiveNoProgressTurns');
217
- expect(noProgressEvent?.currentValue).toBe(3);
218
- expect(noProgressEvent?.message).toContain('until new input arrives');
219
- expect(session.state.agents.get(entryAgentId)?.status).toBe('pending');
220
- // The stop is recoverable without agents.resume or human intervention.
221
- await session.sendAndWaitForIdle('Now do real work');
222
- expect(inferenceCount).toBe(5);
223
- expect(session.state.agents.get(entryAgentId)?.status).toBe('pending');
224
- await harness.shutdown();
225
- });
226
- it('communication-only replies to distinct user messages do not count as no progress', async () => {
227
- let inferenceCount = 0;
228
- let allowProcessing = false;
229
- const preset = createTestPreset({
230
- orchestratorSystem: 'Test agent.',
231
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({
232
- limits: { maxConsecutiveNoProgressTurns: 3, maxTurns: 100 },
233
- })],
234
- });
235
- preset.orchestrator.debounceCallback = () => {
236
- if (!allowProcessing)
237
- return 'wait';
238
- allowProcessing = false;
239
- return 'process_now';
240
- };
241
- preset.orchestrator.checkIntervalMs = 1;
242
- const harness = createLimitsHarness({
243
- presets: [preset],
244
- mockHandler: () => {
245
- inferenceCount++;
246
- return {
247
- content: null,
248
- toolCalls: [{
249
- id: ToolCallId(`reply-${inferenceCount}`),
250
- name: 'tell_user',
251
- input: { message: `Reply ${inferenceCount}` },
252
- }],
253
- finishReason: 'stop',
254
- metrics: MockLLMProvider.defaultMetrics(),
255
- };
256
- },
257
- });
258
- const session = await harness.createSession('test');
259
- const entryAgentId = session.getEntryAgentId();
260
- for (let messageNumber = 1; messageNumber <= 3; messageNumber++) {
261
- await session.sendMessage(`User message ${messageNumber}`);
262
- allowProcessing = true;
263
- await waitUntil(() => {
264
- const state = session.state.agents.get(entryAgentId);
265
- return inferenceCount === messageNumber && state?.pendingToolResults.length === 1;
266
- });
267
- const counters = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
268
- expect(counters?.consecutiveNoProgressTurns).toBe(0);
269
- }
270
- const consumedEvents = await session.getEventsByType(agentEvents, 'agent_input_consumed');
271
- expect(consumedEvents).toHaveLength(3);
272
- expect(consumedEvents.every((event) => event.sourcePlugins.includes('user-chat'))).toBe(true);
273
- const pauseEvents = await session.getEventsByType(agentEvents, 'agent_paused');
274
- expect(pauseEvents.some((event) => event.agentId === entryAgentId)).toBe(false);
275
- const warningEvents = await session.getEventsByType(limitsEvents, 'limit_warning');
276
- expect(warningEvents.some((event) => event.limitName === 'maxConsecutiveNoProgressTurns')).toBe(false);
277
- await harness.shutdown();
278
- });
279
- it('send_message followed by non-communication work does not trip the no-progress limit', async () => {
280
- let workerInferenceCount = 0;
281
- let workCount = 0;
282
- const recordWork = createTool({
283
- name: 'record_work',
284
- description: 'Record one unit of real work.',
285
- input: z.object({}),
286
- execute: async () => {
287
- workCount++;
288
- return Ok('work recorded');
289
- },
290
- });
291
- const harness = createLimitsHarness({
292
- presets: [createMultiAgentPreset([
293
- {
294
- name: 'worker',
295
- system: 'Worker agent.',
296
- tools: [recordWork],
297
- agents: [],
298
- plugins: [limitsGuardPlugin.configureAgent({
299
- limits: { maxConsecutiveNoProgressTurns: 2, maxTurns: 100 },
300
- })],
301
- },
302
- ], { orchestratorSystem: 'Orchestrator agent.' })],
303
- mockHandler: (request) => {
304
- if (request.systemPrompt.endsWith('Orchestrator agent.')) {
305
- const hasStartedWorker = request.messages.some((message) => message.role === 'assistant'
306
- && message.toolCalls?.some((toolCall) => toolCall.name === 'start_worker'));
307
- if (!hasStartedWorker) {
308
- return {
309
- content: null,
310
- toolCalls: [{ id: ToolCallId('start-worker'), name: 'start_worker', input: { message: 'Do the work' } }],
311
- finishReason: 'stop',
312
- metrics: MockLLMProvider.defaultMetrics(),
313
- };
314
- }
315
- return {
316
- content: 'Orchestration complete',
317
- toolCalls: [],
318
- finishReason: 'stop',
319
- metrics: MockLLMProvider.defaultMetrics(),
320
- };
321
- }
322
- workerInferenceCount++;
323
- switch (workerInferenceCount) {
324
- case 1:
325
- return {
326
- content: null,
327
- toolCalls: [{
328
- id: ToolCallId('worker-progress'),
329
- name: 'send_message',
330
- input: { to: 'parent', message: 'Starting real work' },
331
- }],
332
- finishReason: 'stop',
333
- metrics: MockLLMProvider.defaultMetrics(),
334
- };
335
- case 2:
336
- return {
337
- content: null,
338
- toolCalls: [{ id: ToolCallId('worker-work'), name: 'record_work', input: {} }],
339
- finishReason: 'stop',
340
- metrics: MockLLMProvider.defaultMetrics(),
341
- };
342
- case 3:
343
- return {
344
- content: null,
345
- toolCalls: [{
346
- id: ToolCallId('worker-result'),
347
- name: 'send_message',
348
- input: { to: 'parent', message: 'Real work complete' },
349
- }],
350
- finishReason: 'stop',
351
- metrics: MockLLMProvider.defaultMetrics(),
352
- };
353
- default:
354
- return {
355
- content: 'WAITING',
356
- toolCalls: [],
357
- finishReason: 'stop',
358
- metrics: MockLLMProvider.defaultMetrics(),
359
- };
360
- }
361
- },
362
- });
363
- const session = await harness.createSession('test');
364
- await session.sendAndWaitForIdle('Start', { timeoutMs: 10_000 });
365
- expect(workCount).toBe(1);
366
- expect(workerInferenceCount).toBe(4);
367
- expect(session.state.agents.get(AgentId('worker_1'))?.status).toBe('pending');
368
- const pauseEvents = await session.getEventsByType(agentEvents, 'agent_paused');
369
- expect(pauseEvents.some((event) => event.agentId === AgentId('worker_1'))).toBe(false);
370
- await harness.shutdown();
371
- });
372
- });
373
- // =========================================================================
374
- // soft limits (status display)
375
- // =========================================================================
376
- describe('soft limits (status display)', () => {
377
- it('approaching limit (80%) → status contains warning message', async () => {
378
- let inferenceCount = 0;
379
- let sawWarning = false;
380
- const harness = createLimitsHarness({
381
- presets: [createTestPreset({
382
- orchestratorSystem: 'Test agent.',
383
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({
384
- limits: { maxTurns: 5, maxConsecutiveNoProgressTurns: 100 },
385
- })],
386
- })],
387
- mockHandler: (request) => {
388
- inferenceCount++;
389
- const messagesStr = JSON.stringify(request.messages);
390
- if (messagesStr.includes('Approaching maxTurns limit')) {
391
- sawWarning = true;
392
- }
393
- if (inferenceCount < 5) {
394
- return {
395
- content: null,
396
- toolCalls: [{ id: ToolCallId(`tc${inferenceCount}`), name: 'tell_user', input: { message: `Turn ${inferenceCount}` } }],
397
- finishReason: 'stop',
398
- metrics: MockLLMProvider.defaultMetrics(),
399
- };
400
- }
401
- return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
402
- },
403
- });
404
- const session = await harness.createSession('test');
405
- const entryAgentId = session.getEntryAgentId();
406
- await session.sendMessage('Start');
407
- // Agent will be paused at turn 5 or finish at turn 5 if last response has no tools
408
- await waitForAllSettled(session);
409
- expect(sawWarning).toBe(true);
410
- await harness.shutdown();
411
- });
412
- });
413
- // =========================================================================
414
- // counter tracking
415
- // =========================================================================
416
- describe('counter tracking', () => {
417
- it('each inference increments inferenceCount', async () => {
418
- let callCount = 0;
419
- const harness = createLimitsHarness({
420
- presets: [createTestPreset({
421
- orchestratorSystem: 'Test agent.',
422
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxTurns: 100 } })],
423
- })],
424
- mockHandler: () => {
425
- callCount++;
426
- if (callCount <= 2) {
427
- return {
428
- content: null,
429
- toolCalls: [{ id: ToolCallId(`tc${callCount}`), name: 'tell_user', input: { message: `Msg ${callCount}` } }],
430
- finishReason: 'stop',
431
- metrics: MockLLMProvider.defaultMetrics(),
432
- };
433
- }
434
- return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
435
- },
436
- });
437
- const session = await harness.createSession('test');
438
- await session.sendAndWaitForIdle('Start');
439
- const counters = selectPluginState(session.state, 'agentLimits')?.get(session.getEntryAgentId());
440
- expect(counters).toBeDefined();
441
- expect(counters.inferenceCount).toBe(3); // 2 with tools + 1 final
442
- await harness.shutdown();
443
- });
444
- it('each tool call increments toolCallCount', async () => {
445
- let callCount = 0;
446
- const harness = createLimitsHarness({
447
- presets: [createTestPreset({
448
- orchestratorSystem: 'Test agent.',
449
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxTurns: 100 } })],
450
- })],
451
- mockHandler: () => {
452
- callCount++;
453
- if (callCount === 1) {
454
- return {
455
- content: null,
456
- toolCalls: [
457
- { id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'A' } },
458
- { id: ToolCallId('tc2'), name: 'tell_user', input: { message: 'B' } },
459
- ],
460
- finishReason: 'stop',
461
- metrics: MockLLMProvider.defaultMetrics(),
462
- };
463
- }
464
- return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
465
- },
466
- });
467
- const session = await harness.createSession('test');
468
- await session.sendAndWaitForIdle('Start');
469
- const counters = selectPluginState(session.state, 'agentLimits')?.get(session.getEntryAgentId());
470
- expect(counters).toBeDefined();
471
- expect(counters.toolCallCount).toBe(2);
472
- await harness.shutdown();
473
- });
474
- it('each agent spawn increments parent spawnedAgentCount', async () => {
475
- let orchestratorCalls = 0;
476
- const harness = createLimitsHarness({
477
- presets: [createMultiAgentPreset([
478
- { name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
479
- ], { orchestratorSystem: 'Orchestrator agent.' })],
480
- mockHandler: (request) => {
481
- if (request.systemPrompt.includes('Orchestrator')) {
482
- orchestratorCalls++;
483
- if (orchestratorCalls === 1) {
484
- return {
485
- content: null,
486
- toolCalls: [
487
- { id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Task 1' } },
488
- { id: ToolCallId('tc2'), name: 'start_worker', input: { message: 'Task 2' } },
489
- ],
490
- finishReason: 'stop',
491
- metrics: MockLLMProvider.defaultMetrics(),
492
- };
493
- }
494
- return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
495
- }
496
- return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
497
- },
498
- });
499
- const session = await harness.createSession('test');
500
- await session.sendAndWaitForIdle('Start', { timeoutMs: 10000 });
501
- const orchestratorId = session.getEntryAgentId();
502
- const counters = selectPluginState(session.state, 'agentLimits')?.get(orchestratorId);
503
- expect(counters).toBeDefined();
504
- expect(counters.spawnedAgentCount).toBe(2);
505
- await harness.shutdown();
506
- });
507
- it('each mailbox message increments sender messagesSentCount', async () => {
508
- let orchestratorCalls = 0;
509
- let workerCalls = 0;
510
- const harness = createLimitsHarness({
511
- presets: [createMultiAgentPreset([
512
- { name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
513
- ], { orchestratorSystem: 'Orchestrator agent.' })],
514
- mockHandler: (request) => {
515
- if (request.systemPrompt.includes('Orchestrator')) {
516
- orchestratorCalls++;
517
- if (orchestratorCalls === 1) {
518
- return {
519
- content: null,
520
- toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Task' } }],
521
- finishReason: 'stop',
522
- metrics: MockLLMProvider.defaultMetrics(),
523
- };
524
- }
525
- return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
526
- }
527
- workerCalls++;
528
- if (workerCalls === 1) {
529
- return {
530
- content: null,
531
- toolCalls: [{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'parent', message: 'Report' } }],
532
- finishReason: 'stop',
533
- metrics: MockLLMProvider.defaultMetrics(),
534
- };
535
- }
536
- return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
537
- },
538
- });
539
- const session = await harness.createSession('test');
540
- await session.sendAndWaitForIdle('Start', { timeoutMs: 10000 });
541
- const workerCounters = selectPluginState(session.state, 'agentLimits')?.get(AgentId('worker_1'));
542
- expect(workerCounters).toBeDefined();
543
- expect(workerCounters.messagesSentCount).toBeGreaterThanOrEqual(1);
544
- await harness.shutdown();
545
- });
546
- });
547
- // =========================================================================
548
- // resume resets
549
- // =========================================================================
550
- describe('resume resets', () => {
551
- it('agent_resumed → pattern-based counters reset, cumulative counters preserved', async () => {
552
- const harness = createLimitsHarness({
553
- presets: [createTestPreset({
554
- orchestratorSystem: 'Test agent.',
555
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({
556
- limits: { maxRepeatedResponses: 2, maxTurns: 100 },
557
- })],
558
- })],
559
- // Always return the same text → triggers maxRepeatedResponses
560
- mockHandler: () => ({
561
- content: 'I am stuck',
562
- toolCalls: [],
563
- finishReason: 'stop',
564
- metrics: MockLLMProvider.defaultMetrics(),
565
- }),
566
- });
567
- const session = await harness.createSession('test');
568
- const entryAgentId = session.getEntryAgentId();
569
- // 1st identical response → ok → idle
570
- await session.sendAndWaitForIdle('Message 1');
571
- // 2nd identical response → maxRepeatedResponses = 2 → paused
572
- await session.sendMessage('Message 2');
573
- await waitForAgentPaused(session, entryAgentId);
574
- expect(session.state.agents.get(entryAgentId).status).toBe('paused');
575
- // Resume the agent
576
- const resumeResult = await session.callPluginMethod('agents.resume', {
577
- agentId: String(entryAgentId),
578
- });
579
- expect(resumeResult.ok).toBe(true);
580
- // All counters should be reset after resume
581
- const countersAfterResume = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
582
- expect(countersAfterResume).toBeDefined();
583
- expect(countersAfterResume.inferenceCount).toBe(0);
584
- expect(countersAfterResume.toolCallCount).toBe(0);
585
- expect(countersAfterResume.recentResponseHashes).toEqual([]);
586
- // Agent resumes with reset counters. Wait for it to settle (no work → idle).
587
- await session.waitForIdle();
588
- // Send 2 more messages to hit the limit again
589
- await session.sendAndWaitForIdle('Message 3');
590
- await session.sendMessage('Message 4');
591
- await waitForAgentPaused(session, entryAgentId);
592
- const resumedEvents = await session.getEventsByType(agentEvents, 'agent_resumed');
593
- expect(resumedEvents.filter(e => e.agentId === entryAgentId)).toHaveLength(1);
594
- await harness.shutdown();
595
- });
596
- });
597
- // =========================================================================
598
- // budgets (cost / tokens)
599
- // =========================================================================
600
- describe('budgets', () => {
601
- it('agent exceeding cost budget → paused with budget_exceeded event', async () => {
602
- let n = 0;
603
- const harness = createLimitsHarness({
604
- presets: [createTestPreset({
605
- orchestratorSystem: 'Test agent.',
606
- // $0.50 per call, $1.00 budget → pauses before the 3rd call.
607
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxCost: 1.0, maxTurns: 100 } })],
608
- })],
609
- mockHandler: () => {
610
- n++;
611
- return {
612
- content: null,
613
- toolCalls: [{ id: ToolCallId(`tc${n}`), name: 'tell_user', input: { message: `Turn ${n}` } }],
614
- finishReason: 'stop',
615
- metrics: MockLLMProvider.defaultMetricsWithCost(0.5),
616
- };
617
- },
618
- });
619
- const session = await harness.createSession('test');
620
- const entryAgentId = session.getEntryAgentId();
621
- await session.sendMessage('Start');
622
- await waitForAgentPaused(session, entryAgentId);
623
- expect(session.state.agents.get(entryAgentId).status).toBe('paused');
624
- const counters = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
625
- expect(counters.costSpent).toBeGreaterThanOrEqual(1.0);
626
- const budgetEvents = await session.getEventsByType(limitsEvents, 'budget_exceeded');
627
- const evt = budgetEvents.find(e => e.agentId === entryAgentId);
628
- expect(evt).toBeDefined();
629
- expect(evt.scope).toBe('agent');
630
- expect(evt.limitName).toBe('maxCost');
631
- await harness.shutdown();
632
- });
633
- it('costSpent is preserved across resume — budget cannot be bypassed by pausing', async () => {
634
- let n = 0;
635
- const harness = createLimitsHarness({
636
- presets: [createTestPreset({
637
- orchestratorSystem: 'Test agent.',
638
- orchestratorPlugins: [limitsGuardPlugin.configureAgent({ limits: { maxCost: 1.0, maxTurns: 100 } })],
639
- })],
640
- mockHandler: () => {
641
- n++;
642
- return {
643
- content: null,
644
- toolCalls: [{ id: ToolCallId(`tc${n}`), name: 'tell_user', input: { message: `Turn ${n}` } }],
645
- finishReason: 'stop',
646
- metrics: MockLLMProvider.defaultMetricsWithCost(0.5),
647
- };
648
- },
649
- });
650
- const session = await harness.createSession('test');
651
- const entryAgentId = session.getEntryAgentId();
652
- await session.sendMessage('Start');
653
- await waitForAgentPaused(session, entryAgentId);
654
- const before = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
655
- expect(before).toBeDefined();
656
- expect(before.costSpent).toBeGreaterThanOrEqual(1.0);
657
- await session.callPluginMethod('agents.resume', { agentId: String(entryAgentId) });
658
- // Budget is still exhausted → agent pauses again immediately without inferring.
659
- await waitForAgentPaused(session, entryAgentId);
660
- const after = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
661
- expect(after).toBeDefined();
662
- // Anti-looping counter reset…
663
- expect(after.inferenceCount).toBe(0);
664
- // …but spend preserved, so the cap is not bypassable.
665
- expect(after.costSpent).toBeGreaterThanOrEqual(before.costSpent);
666
- await harness.shutdown();
667
- });
668
- it('child pausing on budget → parent is notified via a child-paused message', async () => {
669
- let orchestratorCalls = 0;
670
- let workerCalls = 0;
671
- const harness = createLimitsHarness({
672
- presets: [createTestPreset({
673
- orchestratorSystem: 'Orchestrator agent.',
674
- agents: [{
675
- name: 'worker',
676
- system: 'Worker agent.',
677
- tools: [],
678
- agents: [],
679
- // $0.50 per call, $0.50 budget → pauses at the 2nd inference's
680
- // beforeInference (after one completed call spent the budget).
681
- plugins: [limitsGuardPlugin.configureAgent({ limits: { maxCost: 0.5, maxTurns: 100 } })],
682
- }],
683
- })],
684
- mockHandler: (request) => {
685
- // Worker: keep spending until the budget pauses it.
686
- if (request.systemPrompt.includes('Worker agent.')) {
687
- workerCalls++;
688
- return {
689
- content: null,
690
- toolCalls: [{ id: ToolCallId(`w${workerCalls}`), name: 'tell_user', input: { message: `Work ${workerCalls}` } }],
691
- finishReason: 'stop',
692
- metrics: MockLLMProvider.defaultMetricsWithCost(0.5),
693
- };
694
- }
695
- // Orchestrator: spawn the worker exactly once, then idle.
696
- orchestratorCalls++;
697
- if (orchestratorCalls === 1) {
698
- return {
699
- content: null,
700
- toolCalls: [{ id: ToolCallId('spawn'), name: 'start_worker', input: { message: 'Do work' } }],
701
- finishReason: 'stop',
702
- metrics: MockLLMProvider.defaultMetrics(),
703
- };
704
- }
705
- return { content: 'Waiting', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
706
- },
707
- });
708
- const session = await harness.createSession('test');
709
- await session.sendMessage('Start');
710
- await waitForAgentPaused(session, AgentId('worker_1'));
711
- const orchestratorId = session.getEntryAgentId();
712
- // The mailbox plugin's onPause hook reports the pause to the parent.
713
- // onPause runs *after* the agent_paused event (which flips status to
714
- // 'paused'), so poll for the notification.
715
- const findNotice = async () => (await session.getEventsByType(mailboxEvents, 'mailbox_message')).find(m => m.toAgentId === orchestratorId
716
- && m.message.from === AgentId('worker_1')
717
- && m.message.content.includes('<child-paused')
718
- && m.message.content.includes('worker_1'));
719
- let notice = await findNotice();
720
- const deadline = Date.now() + 5000;
721
- while (!notice && Date.now() < deadline) {
722
- await new Promise(r => setTimeout(r, 20));
723
- notice = await findNotice();
724
- }
725
- expect(notice).toBeDefined();
726
- await harness.shutdown();
727
- });
728
- it('child-paused notice is actually consumed by a parent that already went idle', async () => {
729
- // Regression guard for the lifecycle: a parent that finished its work is
730
- // NOT in a terminal "complete" state — it's persisted as `pending` with an
731
- // empty mailbox. When the child pauses and delivers <child-paused>, the
732
- // dequeue check flips the parent's decide() from "complete" back to "infer",
733
- // so the parent wakes and reads the message rather than leaving it unconsumed.
734
- let workerCalls = 0;
735
- let orchestratorSawChildPaused = false;
736
- const requestHasChildPaused = (request) => request.messages.some((m) => {
737
- const c = typeof m.content === 'string' ? m.content : JSON.stringify(m.content);
738
- return c.includes('<child-paused');
739
- });
740
- const harness = createLimitsHarness({
741
- presets: [createTestPreset({
742
- orchestratorSystem: 'Orchestrator agent.',
743
- agents: [{
744
- name: 'worker',
745
- system: 'Worker agent.',
746
- tools: [],
747
- agents: [],
748
- plugins: [limitsGuardPlugin.configureAgent({ limits: { maxCost: 0.5, maxTurns: 100 } })],
749
- }],
750
- })],
751
- mockHandler: (request) => {
752
- if (request.systemPrompt.includes('Worker agent.')) {
753
- workerCalls++;
754
- return {
755
- content: null,
756
- toolCalls: [{ id: ToolCallId(`w${workerCalls}`), name: 'tell_user', input: { message: `Work ${workerCalls}` } }],
757
- finishReason: 'stop',
758
- metrics: MockLLMProvider.defaultMetricsWithCost(0.5),
759
- };
760
- }
761
- // Orchestrator: spawn the worker once, then go idle. Any later wake-up
762
- // is driven by an incoming message — record if it carried the notice.
763
- if (requestHasChildPaused(request))
764
- orchestratorSawChildPaused = true;
765
- if (workerCalls === 0) {
766
- return {
767
- content: null,
768
- toolCalls: [{ id: ToolCallId('spawn'), name: 'start_worker', input: { message: 'Do work' } }],
769
- finishReason: 'stop',
770
- metrics: MockLLMProvider.defaultMetrics(),
771
- };
772
- }
773
- return { content: 'Acknowledged', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
774
- },
775
- });
776
- const session = await harness.createSession('test');
777
- await session.sendMessage('Start');
778
- await waitForAgentPaused(session, AgentId('worker_1'));
779
- // The parent should wake from idle and run an inference that includes the
780
- // <child-paused> message — proving the notice is consumed, not orphaned.
781
- const deadline = Date.now() + 5000;
782
- while (!orchestratorSawChildPaused && Date.now() < deadline) {
783
- await new Promise(r => setTimeout(r, 20));
784
- }
785
- expect(orchestratorSawChildPaused).toBe(true);
786
- // And the message is marked consumed in the parent's mailbox.
787
- const orchestratorId = session.getEntryAgentId();
788
- const mailbox = getAgentMailbox(selectMailboxState(session.state), orchestratorId);
789
- const childPausedMsg = mailbox.find((m) => m.content.includes('<child-paused'));
790
- expect(childPausedMsg).toBeDefined();
791
- expect(childPausedMsg.consumed).toBe(true);
792
- await harness.shutdown();
793
- });
794
- it('compaction (auxiliary inference) cost counts toward the budget', async () => {
795
- // The compaction summarization is a real, billed LLM call routed through
796
- // runAuxiliaryInference → auxiliary_inference_completed. It must be charged
797
- // against the cost budget, otherwise an agent could spend unboundedly on
798
- // compaction without ever tripping its cap.
799
- const REGULAR_COST = 0.1;
800
- const SUMMARY_COST = 5.0;
801
- // Compaction request detection: inline compaction appends a trailing user
802
- // message containing the summarization marker.
803
- const isSummarizationRequest = (request) => {
804
- const last = request.messages[request.messages.length - 1];
805
- if (!last || last.role !== 'user')
806
- return false;
807
- const content = typeof last.content === 'string' ? last.content : JSON.stringify(last.content);
808
- return content.includes('[CONTEXT COMPACTION REQUEST]');
809
- };
810
- const harness = new TestHarness({
811
- systemPlugins: [contextCompactPlugin, limitsGuardPlugin],
812
- presets: [createTestPreset({
813
- orchestratorSystem: 'Test agent.',
814
- plugins: [
815
- contextCompactPlugin.configure({
816
- compaction: { model: ModelId('mock'), maxTokens: 10, keepRecentMessages: 2 },
817
- }),
818
- ],
819
- // Budget large enough to survive the cheap regular turns but small
820
- // enough that one expensive summarization call blows past it.
821
- orchestratorPlugins: [
822
- limitsGuardPlugin.configureAgent({ limits: { maxCost: 2.0, maxTurns: 100 } }),
823
- ],
824
- })],
825
- mockHandler: (request) => {
826
- if (isSummarizationRequest(request)) {
827
- return {
828
- content: 'Summary of conversation so far.',
829
- toolCalls: [],
830
- finishReason: 'stop',
831
- metrics: MockLLMProvider.defaultMetricsWithCost(SUMMARY_COST),
832
- };
833
- }
834
- return {
835
- content: 'Agent response with some content to increase token count.',
836
- toolCalls: [],
837
- finishReason: 'stop',
838
- metrics: MockLLMProvider.defaultMetricsWithCost(REGULAR_COST),
839
- };
840
- },
841
- });
842
- const session = await harness.createSession('test');
843
- const entryAgentId = session.getEntryAgentId();
844
- // Returns once the agent is either idle or paused — used because we don't
845
- // know up front whether the compaction cost trips the budget on the same
846
- // turn (depends on beforeInference hook ordering) or on the next one.
847
- const waitForIdleOrPaused = async (timeoutMs = 10000) => {
848
- const deadline = Date.now() + timeoutMs;
849
- while (Date.now() < deadline) {
850
- const st = session.state.agents.get(entryAgentId);
851
- if (st?.status === 'paused')
852
- return 'paused';
853
- if (st?.status === 'pending' && st.pendingToolCalls.length === 0 && st.pendingToolResults.length === 0) {
854
- return 'idle';
855
- }
856
- await new Promise(r => setTimeout(r, 10));
857
- }
858
- throw new Error('waitForIdleOrPaused timed out');
859
- };
860
- await session.sendAndWaitForIdle('First message');
861
- await session.sendAndWaitForIdle('Second message');
862
- // Third message triggers compaction (the expensive summarization call).
863
- // It may pause on this turn or settle idle and pause on the next one.
864
- await session.sendMessage('Third message to trigger compaction');
865
- if (await waitForIdleOrPaused() === 'idle') {
866
- await session.sendMessage('Fourth message');
867
- }
868
- await waitForAgentPaused(session, entryAgentId);
869
- // Compaction genuinely ran and was billed.
870
- const auxEvents = await session.getEventsByType(llmEvents, 'auxiliary_inference_completed');
871
- expect(auxEvents.some((e) => e.metrics.cost === SUMMARY_COST)).toBe(true);
872
- // The summarization cost is reflected in the agent's tracked spend…
873
- const counters = selectPluginState(session.state, 'agentLimits')?.get(entryAgentId);
874
- expect(counters).toBeDefined();
875
- expect(counters.costSpent).toBeGreaterThanOrEqual(SUMMARY_COST);
876
- // …and it tripped the cost budget (the regular turns alone, at 0.1 each,
877
- // could never reach the 2.0 cap on their own here).
878
- const budgetEvents = await session.getEventsByType(limitsEvents, 'budget_exceeded');
879
- const evt = budgetEvents.find((e) => e.agentId === entryAgentId);
880
- expect(evt).toBeDefined();
881
- expect(evt.scope).toBe('agent');
882
- expect(evt.limitName).toBe('maxCost');
883
- await harness.shutdown();
884
- });
885
- });
886
- });
887
- //# sourceMappingURL=limits-guard.integration.test.js.map