@roj-ai/sdk 0.1.3 → 0.1.5

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 (493) hide show
  1. package/dist/bootstrap.js +191 -0
  2. package/dist/bootstrap.js.map +1 -0
  3. package/dist/builtin-events.js +8 -0
  4. package/dist/builtin-events.js.map +1 -0
  5. package/dist/bun-platform/fs.js +39 -0
  6. package/dist/bun-platform/fs.js.map +1 -0
  7. package/dist/bun-platform/index.js +18 -0
  8. package/dist/bun-platform/index.js.map +1 -0
  9. package/dist/bun-platform/process.js +21 -0
  10. package/dist/bun-platform/process.js.map +1 -0
  11. package/dist/config.js +54 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/config.test.js +155 -0
  14. package/dist/config.test.js.map +1 -0
  15. package/dist/core/agent-loop.integration.test.js +414 -0
  16. package/dist/core/agent-loop.integration.test.js.map +1 -0
  17. package/dist/core/agents/agent-config.test.js +194 -0
  18. package/dist/core/agents/agent-config.test.js.map +1 -0
  19. package/dist/core/agents/agent-roles.js +25 -0
  20. package/dist/core/agents/agent-roles.js.map +1 -0
  21. package/dist/core/agents/agent-shutdown.test.js +180 -0
  22. package/dist/core/agents/agent-shutdown.test.js.map +1 -0
  23. package/dist/core/agents/agent.js +1205 -0
  24. package/dist/core/agents/agent.js.map +1 -0
  25. package/dist/core/agents/agent.test.js +313 -0
  26. package/dist/core/agents/agent.test.js.map +1 -0
  27. package/dist/core/agents/communicator.js +13 -0
  28. package/dist/core/agents/communicator.js.map +1 -0
  29. package/dist/core/agents/config.js +5 -0
  30. package/dist/core/agents/config.js.map +1 -0
  31. package/dist/core/agents/context.js +2 -0
  32. package/dist/core/agents/context.js.map +1 -0
  33. package/dist/core/agents/debounce.js +74 -0
  34. package/dist/core/agents/debounce.js.map +1 -0
  35. package/dist/core/agents/handler-events.test.js +115 -0
  36. package/dist/core/agents/handler-events.test.js.map +1 -0
  37. package/dist/core/agents/index.js +2 -0
  38. package/dist/core/agents/index.js.map +1 -0
  39. package/dist/core/agents/response-sanitizer.js +46 -0
  40. package/dist/core/agents/response-sanitizer.js.map +1 -0
  41. package/dist/core/agents/response-sanitizer.test.js +101 -0
  42. package/dist/core/agents/response-sanitizer.test.js.map +1 -0
  43. package/dist/core/agents/retry.js +105 -0
  44. package/dist/core/agents/retry.js.map +1 -0
  45. package/dist/core/agents/schema.js +39 -0
  46. package/dist/core/agents/schema.js.map +1 -0
  47. package/dist/core/agents/state.js +90 -0
  48. package/dist/core/agents/state.js.map +1 -0
  49. package/dist/core/context/state.js +23 -0
  50. package/dist/core/context/state.js.map +1 -0
  51. package/dist/core/errors.js +38 -0
  52. package/dist/core/errors.js.map +1 -0
  53. package/dist/core/event-sourcing.integration.test.js +154 -0
  54. package/dist/core/event-sourcing.integration.test.js.map +1 -0
  55. package/dist/core/events/base-event-store.js +201 -0
  56. package/dist/core/events/base-event-store.js.map +1 -0
  57. package/dist/core/events/event-store.js +26 -0
  58. package/dist/core/events/event-store.js.map +1 -0
  59. package/dist/core/events/file.js +320 -0
  60. package/dist/core/events/file.js.map +1 -0
  61. package/dist/core/events/file.test.js +284 -0
  62. package/dist/core/events/file.test.js.map +1 -0
  63. package/dist/core/events/index.js +3 -0
  64. package/dist/core/events/index.js.map +1 -0
  65. package/dist/core/events/memory.js +101 -0
  66. package/dist/core/events/memory.js.map +1 -0
  67. package/dist/core/events/memory.test.js +502 -0
  68. package/dist/core/events/memory.test.js.map +1 -0
  69. package/dist/core/events/metadata-utils.js +107 -0
  70. package/dist/core/events/metadata-utils.js.map +1 -0
  71. package/dist/core/events/test-helpers.js +15 -0
  72. package/dist/core/events/test-helpers.js.map +1 -0
  73. package/dist/core/events/types.js +21 -0
  74. package/dist/core/events/types.js.map +1 -0
  75. package/dist/core/file-store/file-store.js +250 -0
  76. package/dist/core/file-store/file-store.js.map +1 -0
  77. package/dist/core/file-store/types.js +7 -0
  78. package/dist/core/file-store/types.js.map +1 -0
  79. package/dist/core/image/image-processor.js +106 -0
  80. package/dist/core/image/image-processor.js.map +1 -0
  81. package/dist/core/image/image-processor.test.js +171 -0
  82. package/dist/core/image/image-processor.test.js.map +1 -0
  83. package/dist/core/image/index.js +4 -0
  84. package/dist/core/image/index.js.map +1 -0
  85. package/dist/core/image/noop-resizer.js +6 -0
  86. package/dist/core/image/noop-resizer.js.map +1 -0
  87. package/dist/core/image/types.js +2 -0
  88. package/dist/core/image/types.js.map +1 -0
  89. package/dist/core/image/vips-resizer.js +100 -0
  90. package/dist/core/image/vips-resizer.js.map +1 -0
  91. package/dist/core/image/vips-resizer.test.js +324 -0
  92. package/dist/core/image/vips-resizer.test.js.map +1 -0
  93. package/dist/core/llm/anthropic.js +396 -0
  94. package/dist/core/llm/anthropic.js.map +1 -0
  95. package/dist/core/llm/anthropic.test.js +434 -0
  96. package/dist/core/llm/anthropic.test.js.map +1 -0
  97. package/dist/core/llm/cache-breakpoints.js +37 -0
  98. package/dist/core/llm/cache-breakpoints.js.map +1 -0
  99. package/dist/core/llm/cache-live.test.js +137 -0
  100. package/dist/core/llm/cache-live.test.js.map +1 -0
  101. package/dist/core/llm/index.js +9 -0
  102. package/dist/core/llm/index.js.map +1 -0
  103. package/dist/core/llm/llm-log-types.js +12 -0
  104. package/dist/core/llm/llm-log-types.js.map +1 -0
  105. package/dist/core/llm/logger.js +241 -0
  106. package/dist/core/llm/logger.js.map +1 -0
  107. package/dist/core/llm/logger.test.js +228 -0
  108. package/dist/core/llm/logger.test.js.map +1 -0
  109. package/dist/core/llm/logging-provider.js +49 -0
  110. package/dist/core/llm/logging-provider.js.map +1 -0
  111. package/dist/core/llm/middleware.js +114 -0
  112. package/dist/core/llm/middleware.js.map +1 -0
  113. package/dist/core/llm/mock.js +186 -0
  114. package/dist/core/llm/mock.js.map +1 -0
  115. package/dist/core/llm/mock.test.js +318 -0
  116. package/dist/core/llm/mock.test.js.map +1 -0
  117. package/dist/core/llm/openrouter-mapping.test.js +125 -0
  118. package/dist/core/llm/openrouter-mapping.test.js.map +1 -0
  119. package/dist/core/llm/openrouter.js +298 -0
  120. package/dist/core/llm/openrouter.js.map +1 -0
  121. package/dist/core/llm/openrouter.test.js +377 -0
  122. package/dist/core/llm/openrouter.test.js.map +1 -0
  123. package/dist/core/llm/provider-integration.test.js +350 -0
  124. package/dist/core/llm/provider-integration.test.js.map +1 -0
  125. package/dist/core/llm/provider.js +18 -0
  126. package/dist/core/llm/provider.js.map +1 -0
  127. package/dist/core/llm/routing-provider.js +52 -0
  128. package/dist/core/llm/routing-provider.js.map +1 -0
  129. package/dist/core/llm/routing-provider.test.js +94 -0
  130. package/dist/core/llm/routing-provider.test.js.map +1 -0
  131. package/dist/core/llm/schema.js +31 -0
  132. package/dist/core/llm/schema.js.map +1 -0
  133. package/dist/core/llm/snapshot-fetch.js +122 -0
  134. package/dist/core/llm/snapshot-fetch.js.map +1 -0
  135. package/dist/core/llm/snapshot-middleware.js +142 -0
  136. package/dist/core/llm/snapshot-middleware.js.map +1 -0
  137. package/dist/core/llm/snapshot-middleware.test.js +144 -0
  138. package/dist/core/llm/snapshot-middleware.test.js.map +1 -0
  139. package/dist/core/llm/state.js +48 -0
  140. package/dist/core/llm/state.js.map +1 -0
  141. package/dist/core/llm/tokens.js +40 -0
  142. package/dist/core/llm/tokens.js.map +1 -0
  143. package/dist/core/multi-agent.integration.test.js +298 -0
  144. package/dist/core/multi-agent.integration.test.js.map +1 -0
  145. package/dist/core/plugin-hooks.integration.test.js +344 -0
  146. package/dist/core/plugin-hooks.integration.test.js.map +1 -0
  147. package/dist/core/plugins/hook-types.js +5 -0
  148. package/dist/core/plugins/hook-types.js.map +1 -0
  149. package/dist/core/plugins/index.js +5 -0
  150. package/dist/core/plugins/index.js.map +1 -0
  151. package/dist/core/plugins/plugin-builder.js +321 -0
  152. package/dist/core/plugins/plugin-builder.js.map +1 -0
  153. package/dist/core/preset/config.js +54 -0
  154. package/dist/core/preset/config.js.map +1 -0
  155. package/dist/core/preset/index.js +6 -0
  156. package/dist/core/preset/index.js.map +1 -0
  157. package/dist/core/preset/preset-builder.js +63 -0
  158. package/dist/core/preset/preset-builder.js.map +1 -0
  159. package/dist/core/session-lifecycle.integration.test.js +159 -0
  160. package/dist/core/session-lifecycle.integration.test.js.map +1 -0
  161. package/dist/core/sessions/apply-event.js +41 -0
  162. package/dist/core/sessions/apply-event.js.map +1 -0
  163. package/dist/core/sessions/context.js +2 -0
  164. package/dist/core/sessions/context.js.map +1 -0
  165. package/dist/core/sessions/fork-utils.js +42 -0
  166. package/dist/core/sessions/fork-utils.js.map +1 -0
  167. package/dist/core/sessions/fork-utils.test.js +129 -0
  168. package/dist/core/sessions/fork-utils.test.js.map +1 -0
  169. package/dist/core/sessions/reducer.js +55 -0
  170. package/dist/core/sessions/reducer.js.map +1 -0
  171. package/dist/core/sessions/schema.js +66 -0
  172. package/dist/core/sessions/schema.js.map +1 -0
  173. package/dist/core/sessions/session-environment.js +2 -0
  174. package/dist/core/sessions/session-environment.js.map +1 -0
  175. package/dist/core/sessions/session-manager.js +650 -0
  176. package/dist/core/sessions/session-manager.js.map +1 -0
  177. package/dist/core/sessions/session-store.js +118 -0
  178. package/dist/core/sessions/session-store.js.map +1 -0
  179. package/dist/core/sessions/session.js +675 -0
  180. package/dist/core/sessions/session.js.map +1 -0
  181. package/dist/core/sessions/session.test.js +1095 -0
  182. package/dist/core/sessions/session.test.js.map +1 -0
  183. package/dist/core/sessions/state.js +377 -0
  184. package/dist/core/sessions/state.js.map +1 -0
  185. package/dist/core/system.js +66 -0
  186. package/dist/core/system.js.map +1 -0
  187. package/dist/core/tools/context.js +2 -0
  188. package/dist/core/tools/context.js.map +1 -0
  189. package/dist/core/tools/definition.js +4 -0
  190. package/dist/core/tools/definition.js.map +1 -0
  191. package/dist/core/tools/executor.js +82 -0
  192. package/dist/core/tools/executor.js.map +1 -0
  193. package/dist/core/tools/executor.test.js +143 -0
  194. package/dist/core/tools/executor.test.js.map +1 -0
  195. package/dist/core/tools/index.js +4 -0
  196. package/dist/core/tools/index.js.map +1 -0
  197. package/dist/core/tools/schema.js +20 -0
  198. package/dist/core/tools/schema.js.map +1 -0
  199. package/dist/core/tools/state.js +29 -0
  200. package/dist/core/tools/state.js.map +1 -0
  201. package/dist/index.js +70 -0
  202. package/dist/index.js.map +1 -0
  203. package/dist/lib/json/index.js +5 -0
  204. package/dist/lib/json/index.js.map +1 -0
  205. package/dist/lib/logger/console.js +147 -0
  206. package/dist/lib/logger/console.js.map +1 -0
  207. package/dist/lib/logger/console.test.js +258 -0
  208. package/dist/lib/logger/console.test.js.map +1 -0
  209. package/dist/lib/logger/file.js +54 -0
  210. package/dist/lib/logger/file.js.map +1 -0
  211. package/dist/lib/logger/index.js +4 -0
  212. package/dist/lib/logger/index.js.map +1 -0
  213. package/dist/lib/logger/logger.js +28 -0
  214. package/dist/lib/logger/logger.js.map +1 -0
  215. package/dist/lib/logger/ring-buffer.js +61 -0
  216. package/dist/lib/logger/ring-buffer.js.map +1 -0
  217. package/dist/lib/logger/tee.js +43 -0
  218. package/dist/lib/logger/tee.js.map +1 -0
  219. package/dist/lib/mime.js +22 -0
  220. package/dist/lib/mime.js.map +1 -0
  221. package/dist/lib/never.js +4 -0
  222. package/dist/lib/never.js.map +1 -0
  223. package/dist/lib/utils/hash.js +35 -0
  224. package/dist/lib/utils/hash.js.map +1 -0
  225. package/dist/lib/utils/result.js +21 -0
  226. package/dist/lib/utils/result.js.map +1 -0
  227. package/dist/platform/fs.js +8 -0
  228. package/dist/platform/fs.js.map +1 -0
  229. package/dist/platform/index.js +9 -0
  230. package/dist/platform/index.js.map +1 -0
  231. package/dist/platform/process.js +8 -0
  232. package/dist/platform/process.js.map +1 -0
  233. package/dist/plugins/agent-status/plugin.js +77 -0
  234. package/dist/plugins/agent-status/plugin.js.map +1 -0
  235. package/dist/plugins/agents/agents.integration.test.js +683 -0
  236. package/dist/plugins/agents/agents.integration.test.js.map +1 -0
  237. package/dist/plugins/agents/index.js +2 -0
  238. package/dist/plugins/agents/index.js.map +1 -0
  239. package/dist/plugins/agents/plugin.js +199 -0
  240. package/dist/plugins/agents/plugin.js.map +1 -0
  241. package/dist/plugins/context-compact/context-compact.integration.test.js +174 -0
  242. package/dist/plugins/context-compact/context-compact.integration.test.js.map +1 -0
  243. package/dist/plugins/context-compact/context-compactor.js +238 -0
  244. package/dist/plugins/context-compact/context-compactor.js.map +1 -0
  245. package/dist/plugins/context-compact/context-compactor.test.js +763 -0
  246. package/dist/plugins/context-compact/context-compactor.test.js.map +1 -0
  247. package/dist/plugins/context-compact/history-offloader.js +42 -0
  248. package/dist/plugins/context-compact/history-offloader.js.map +1 -0
  249. package/dist/plugins/context-compact/history-offloader.test.js +77 -0
  250. package/dist/plugins/context-compact/history-offloader.test.js.map +1 -0
  251. package/dist/plugins/context-compact/index.js +4 -0
  252. package/dist/plugins/context-compact/index.js.map +1 -0
  253. package/dist/plugins/context-compact/plugin.js +37 -0
  254. package/dist/plugins/context-compact/plugin.js.map +1 -0
  255. package/dist/plugins/filesystem/filesystem.integration.test.js +411 -0
  256. package/dist/plugins/filesystem/filesystem.integration.test.js.map +1 -0
  257. package/dist/plugins/filesystem/helpers.js +170 -0
  258. package/dist/plugins/filesystem/helpers.js.map +1 -0
  259. package/dist/plugins/filesystem/index.js +3 -0
  260. package/dist/plugins/filesystem/index.js.map +1 -0
  261. package/dist/plugins/filesystem/listing.js +247 -0
  262. package/dist/plugins/filesystem/listing.js.map +1 -0
  263. package/dist/plugins/filesystem/plugin.js +364 -0
  264. package/dist/plugins/filesystem/plugin.js.map +1 -0
  265. package/dist/plugins/filesystem/schema.js +2 -0
  266. package/dist/plugins/filesystem/schema.js.map +1 -0
  267. package/dist/plugins/git-status/index.js +2 -0
  268. package/dist/plugins/git-status/index.js.map +1 -0
  269. package/dist/plugins/git-status/plugin.js +144 -0
  270. package/dist/plugins/git-status/plugin.js.map +1 -0
  271. package/dist/plugins/limits-guard/config.js +5 -0
  272. package/dist/plugins/limits-guard/config.js.map +1 -0
  273. package/dist/plugins/limits-guard/index.js +3 -0
  274. package/dist/plugins/limits-guard/index.js.map +1 -0
  275. package/dist/plugins/limits-guard/limit-guard.js +125 -0
  276. package/dist/plugins/limits-guard/limit-guard.js.map +1 -0
  277. package/dist/plugins/limits-guard/limit-guard.test.js +121 -0
  278. package/dist/plugins/limits-guard/limit-guard.test.js.map +1 -0
  279. package/dist/plugins/limits-guard/limits-guard.integration.test.js +378 -0
  280. package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +1 -0
  281. package/dist/plugins/limits-guard/plugin.js +240 -0
  282. package/dist/plugins/limits-guard/plugin.js.map +1 -0
  283. package/dist/plugins/llm-debug/index.js +2 -0
  284. package/dist/plugins/llm-debug/index.js.map +1 -0
  285. package/dist/plugins/llm-debug/llm-debug.integration.test.js +157 -0
  286. package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +1 -0
  287. package/dist/plugins/llm-debug/plugin.js +148 -0
  288. package/dist/plugins/llm-debug/plugin.js.map +1 -0
  289. package/dist/plugins/logs/index.js +2 -0
  290. package/dist/plugins/logs/index.js.map +1 -0
  291. package/dist/plugins/logs/plugin.js +38 -0
  292. package/dist/plugins/logs/plugin.js.map +1 -0
  293. package/dist/plugins/mailbox/helpers.js +66 -0
  294. package/dist/plugins/mailbox/helpers.js.map +1 -0
  295. package/dist/plugins/mailbox/index.js +9 -0
  296. package/dist/plugins/mailbox/index.js.map +1 -0
  297. package/dist/plugins/mailbox/mailbox.integration.test.js +605 -0
  298. package/dist/plugins/mailbox/mailbox.integration.test.js.map +1 -0
  299. package/dist/plugins/mailbox/plugin.js +204 -0
  300. package/dist/plugins/mailbox/plugin.js.map +1 -0
  301. package/dist/plugins/mailbox/prompts.js +93 -0
  302. package/dist/plugins/mailbox/prompts.js.map +1 -0
  303. package/dist/plugins/mailbox/query.js +38 -0
  304. package/dist/plugins/mailbox/query.js.map +1 -0
  305. package/dist/plugins/mailbox/schema.js +32 -0
  306. package/dist/plugins/mailbox/schema.js.map +1 -0
  307. package/dist/plugins/mailbox/state.js +41 -0
  308. package/dist/plugins/mailbox/state.js.map +1 -0
  309. package/dist/plugins/resources/index.js +4 -0
  310. package/dist/plugins/resources/index.js.map +1 -0
  311. package/dist/plugins/resources/manifest.js +20 -0
  312. package/dist/plugins/resources/manifest.js.map +1 -0
  313. package/dist/plugins/resources/plugin.js +171 -0
  314. package/dist/plugins/resources/plugin.js.map +1 -0
  315. package/dist/plugins/resources/post-inject.js +32 -0
  316. package/dist/plugins/resources/post-inject.js.map +1 -0
  317. package/dist/plugins/resources/state.js +16 -0
  318. package/dist/plugins/resources/state.js.map +1 -0
  319. package/dist/plugins/result-eviction/index.js +2 -0
  320. package/dist/plugins/result-eviction/index.js.map +1 -0
  321. package/dist/plugins/result-eviction/plugin.js +43 -0
  322. package/dist/plugins/result-eviction/plugin.js.map +1 -0
  323. package/dist/plugins/result-eviction/result-eviction.integration.test.js +217 -0
  324. package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +1 -0
  325. package/dist/plugins/services/plugin.js +453 -0
  326. package/dist/plugins/services/plugin.js.map +1 -0
  327. package/dist/plugins/services/port-pool.js +70 -0
  328. package/dist/plugins/services/port-pool.js.map +1 -0
  329. package/dist/plugins/services/prompt.js +40 -0
  330. package/dist/plugins/services/prompt.js.map +1 -0
  331. package/dist/plugins/services/schema.js +9 -0
  332. package/dist/plugins/services/schema.js.map +1 -0
  333. package/dist/plugins/services/service.js +470 -0
  334. package/dist/plugins/services/service.js.map +1 -0
  335. package/dist/plugins/services/services.integration.test.js +485 -0
  336. package/dist/plugins/services/services.integration.test.js.map +1 -0
  337. package/dist/plugins/session-lifecycle/index.js +2 -0
  338. package/dist/plugins/session-lifecycle/index.js.map +1 -0
  339. package/dist/plugins/session-lifecycle/plugin.js +273 -0
  340. package/dist/plugins/session-lifecycle/plugin.js.map +1 -0
  341. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +498 -0
  342. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +1 -0
  343. package/dist/plugins/session-state/plugin.js +159 -0
  344. package/dist/plugins/session-state/plugin.js.map +1 -0
  345. package/dist/plugins/session-stats/index.js +3 -0
  346. package/dist/plugins/session-stats/index.js.map +1 -0
  347. package/dist/plugins/session-stats/plugin.js +81 -0
  348. package/dist/plugins/session-stats/plugin.js.map +1 -0
  349. package/dist/plugins/shell/executor.js +339 -0
  350. package/dist/plugins/shell/executor.js.map +1 -0
  351. package/dist/plugins/shell/index.js +6 -0
  352. package/dist/plugins/shell/index.js.map +1 -0
  353. package/dist/plugins/shell/plugin.js +66 -0
  354. package/dist/plugins/shell/plugin.js.map +1 -0
  355. package/dist/plugins/shell/shell.integration.test.js +234 -0
  356. package/dist/plugins/shell/shell.integration.test.js.map +1 -0
  357. package/dist/plugins/shell/shell.test.js +236 -0
  358. package/dist/plugins/shell/shell.test.js.map +1 -0
  359. package/dist/plugins/skills/discovery.js +205 -0
  360. package/dist/plugins/skills/discovery.js.map +1 -0
  361. package/dist/plugins/skills/discovery.test.js +312 -0
  362. package/dist/plugins/skills/discovery.test.js.map +1 -0
  363. package/dist/plugins/skills/index.js +12 -0
  364. package/dist/plugins/skills/index.js.map +1 -0
  365. package/dist/plugins/skills/plugin.js +293 -0
  366. package/dist/plugins/skills/plugin.js.map +1 -0
  367. package/dist/plugins/skills/prompts.js +70 -0
  368. package/dist/plugins/skills/prompts.js.map +1 -0
  369. package/dist/plugins/skills/schema.js +18 -0
  370. package/dist/plugins/skills/schema.js.map +1 -0
  371. package/dist/plugins/skills/skills.integration.test.js +475 -0
  372. package/dist/plugins/skills/skills.integration.test.js.map +1 -0
  373. package/dist/plugins/snapshotting/index.js +3 -0
  374. package/dist/plugins/snapshotting/index.js.map +1 -0
  375. package/dist/plugins/snapshotting/jj-snapshotter.js +106 -0
  376. package/dist/plugins/snapshotting/jj-snapshotter.js.map +1 -0
  377. package/dist/plugins/snapshotting/plugin.js +28 -0
  378. package/dist/plugins/snapshotting/plugin.js.map +1 -0
  379. package/dist/plugins/snapshotting/snapshotter.js +2 -0
  380. package/dist/plugins/snapshotting/snapshotter.js.map +1 -0
  381. package/dist/plugins/todo/index.js +7 -0
  382. package/dist/plugins/todo/index.js.map +1 -0
  383. package/dist/plugins/todo/plugin.js +319 -0
  384. package/dist/plugins/todo/plugin.js.map +1 -0
  385. package/dist/plugins/todo/prompts.js +54 -0
  386. package/dist/plugins/todo/prompts.js.map +1 -0
  387. package/dist/plugins/todo/schema.js +18 -0
  388. package/dist/plugins/todo/schema.js.map +1 -0
  389. package/dist/plugins/todo/todo.integration.test.js +605 -0
  390. package/dist/plugins/todo/todo.integration.test.js.map +1 -0
  391. package/dist/plugins/uploads/index.js +8 -0
  392. package/dist/plugins/uploads/index.js.map +1 -0
  393. package/dist/plugins/uploads/plugin.js +346 -0
  394. package/dist/plugins/uploads/plugin.js.map +1 -0
  395. package/dist/plugins/uploads/preprocessor.js +44 -0
  396. package/dist/plugins/uploads/preprocessor.js.map +1 -0
  397. package/dist/plugins/uploads/preprocessors/image-classifier.js +127 -0
  398. package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -0
  399. package/dist/plugins/uploads/preprocessors/index.js +7 -0
  400. package/dist/plugins/uploads/preprocessors/index.js.map +1 -0
  401. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +204 -0
  402. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -0
  403. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +172 -0
  404. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -0
  405. package/dist/plugins/uploads/schema.js +20 -0
  406. package/dist/plugins/uploads/schema.js.map +1 -0
  407. package/dist/plugins/uploads/state.js +22 -0
  408. package/dist/plugins/uploads/state.js.map +1 -0
  409. package/dist/plugins/uploads/uploads.integration.test.js +496 -0
  410. package/dist/plugins/uploads/uploads.integration.test.js.map +1 -0
  411. package/dist/plugins/user-chat/index.js +5 -0
  412. package/dist/plugins/user-chat/index.js.map +1 -0
  413. package/dist/plugins/user-chat/plugin.js +544 -0
  414. package/dist/plugins/user-chat/plugin.js.map +1 -0
  415. package/dist/plugins/user-chat/prompts.js +29 -0
  416. package/dist/plugins/user-chat/prompts.js.map +1 -0
  417. package/dist/plugins/user-chat/schema.js +46 -0
  418. package/dist/plugins/user-chat/schema.js.map +1 -0
  419. package/dist/plugins/user-chat/user-chat.integration.test.js +668 -0
  420. package/dist/plugins/user-chat/user-chat.integration.test.js.map +1 -0
  421. package/dist/plugins/workers/context.js +143 -0
  422. package/dist/plugins/workers/context.js.map +1 -0
  423. package/dist/plugins/workers/definition.js +30 -0
  424. package/dist/plugins/workers/definition.js.map +1 -0
  425. package/dist/plugins/workers/index.js +7 -0
  426. package/dist/plugins/workers/index.js.map +1 -0
  427. package/dist/plugins/workers/plugin.js +578 -0
  428. package/dist/plugins/workers/plugin.js.map +1 -0
  429. package/dist/plugins/workers/worker.js +18 -0
  430. package/dist/plugins/workers/worker.js.map +1 -0
  431. package/dist/plugins/workers/workers.integration.test.js +629 -0
  432. package/dist/plugins/workers/workers.integration.test.js.map +1 -0
  433. package/dist/prompts/base.js +239 -0
  434. package/dist/prompts/base.js.map +1 -0
  435. package/dist/prompts/builder.js +131 -0
  436. package/dist/prompts/builder.js.map +1 -0
  437. package/dist/prompts/index.js +20 -0
  438. package/dist/prompts/index.js.map +1 -0
  439. package/dist/prompts/macros.js +26 -0
  440. package/dist/prompts/macros.js.map +1 -0
  441. package/dist/prompts/macros.test.js +80 -0
  442. package/dist/prompts/macros.test.js.map +1 -0
  443. package/dist/testing/bootstrap-for-testing.js +28 -0
  444. package/dist/testing/bootstrap-for-testing.js.map +1 -0
  445. package/dist/testing/index.js +7 -0
  446. package/dist/testing/index.js.map +1 -0
  447. package/dist/testing/node-platform.js +65 -0
  448. package/dist/testing/node-platform.js.map +1 -0
  449. package/dist/testing/notification-collector.js +82 -0
  450. package/dist/testing/notification-collector.js.map +1 -0
  451. package/dist/testing/preset-helpers.js +37 -0
  452. package/dist/testing/preset-helpers.js.map +1 -0
  453. package/dist/testing/test-harness.js +226 -0
  454. package/dist/testing/test-harness.js.map +1 -0
  455. package/dist/testing/test-harness.test.js +51 -0
  456. package/dist/testing/test-harness.test.js.map +1 -0
  457. package/dist/testing/wait-helpers.js +64 -0
  458. package/dist/testing/wait-helpers.js.map +1 -0
  459. package/dist/transport/adapter/client-adapter.js +64 -0
  460. package/dist/transport/adapter/client-adapter.js.map +1 -0
  461. package/dist/transport/adapter/index.js +24 -0
  462. package/dist/transport/adapter/index.js.map +1 -0
  463. package/dist/transport/adapter/server-adapter.js +73 -0
  464. package/dist/transport/adapter/server-adapter.js.map +1 -0
  465. package/dist/transport/adapter/types.js +8 -0
  466. package/dist/transport/adapter/types.js.map +1 -0
  467. package/dist/transport/http/app.js +86 -0
  468. package/dist/transport/http/app.js.map +1 -0
  469. package/dist/transport/http/index.js +6 -0
  470. package/dist/transport/http/index.js.map +1 -0
  471. package/dist/transport/http/middleware/bearer-auth.js +33 -0
  472. package/dist/transport/http/middleware/bearer-auth.js.map +1 -0
  473. package/dist/transport/http/middleware/error-handler.js +56 -0
  474. package/dist/transport/http/middleware/error-handler.js.map +1 -0
  475. package/dist/transport/http/routes/files.js +237 -0
  476. package/dist/transport/http/routes/files.js.map +1 -0
  477. package/dist/transport/http/routes/resources.js +77 -0
  478. package/dist/transport/http/routes/resources.js.map +1 -0
  479. package/dist/transport/http/routes/rpc.integration.test.js +189 -0
  480. package/dist/transport/http/routes/rpc.integration.test.js.map +1 -0
  481. package/dist/transport/http/routes/rpc.js +110 -0
  482. package/dist/transport/http/routes/rpc.js.map +1 -0
  483. package/dist/transport/http/routes/rpc.test.js +316 -0
  484. package/dist/transport/http/routes/rpc.test.js.map +1 -0
  485. package/dist/transport/http/routes/upload.js +205 -0
  486. package/dist/transport/http/routes/upload.js.map +1 -0
  487. package/dist/transport/rpc/index.js +7 -0
  488. package/dist/transport/rpc/index.js.map +1 -0
  489. package/dist/transport/rpc/methods.js +8 -0
  490. package/dist/transport/rpc/methods.js.map +1 -0
  491. package/dist/user-config.js +14 -0
  492. package/dist/user-config.js.map +1 -0
  493. package/package.json +47 -57
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Snapshot-caching fetch wrapper for integration tests.
3
+ *
4
+ * On first run (or when request changes), makes a real HTTP call and saves
5
+ * the request+response pair to a JSON snapshot file. On subsequent runs
6
+ * with the same request, returns the cached response without making a call.
7
+ *
8
+ * Usage:
9
+ * const fetch = createSnapshotFetch(snapshotsDir)
10
+ * const provider = new AnthropicProvider({ ..., fetch })
11
+ */
12
+ import { createHash } from 'node:crypto';
13
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
14
+ import { join } from 'node:path';
15
+ /**
16
+ * Deterministic hash of a request (URL + method + body).
17
+ * Headers are excluded because auth headers change between runs.
18
+ */
19
+ function hashRequest(url, method, body) {
20
+ const hash = createHash('sha256');
21
+ hash.update(method);
22
+ hash.update(url);
23
+ hash.update(stableStringify(JSON.parse(body)));
24
+ return hash.digest('hex').slice(0, 16);
25
+ }
26
+ /**
27
+ * JSON.stringify with sorted keys for deterministic output.
28
+ */
29
+ function stableStringify(value) {
30
+ return JSON.stringify(value, (_key, val) => {
31
+ if (val && typeof val === 'object' && !Array.isArray(val)) {
32
+ return Object.fromEntries(Object.entries(val).sort(([a], [b]) => a.localeCompare(b)));
33
+ }
34
+ return val;
35
+ });
36
+ }
37
+ /**
38
+ * Strip sensitive headers (auth) from a headers object for snapshot storage.
39
+ */
40
+ function sanitizeHeaders(headers) {
41
+ const result = {};
42
+ for (const [key, value] of Object.entries(headers)) {
43
+ const lower = key.toLowerCase();
44
+ if (lower === 'authorization' || lower === 'x-api-key')
45
+ continue;
46
+ result[key] = value;
47
+ }
48
+ return result;
49
+ }
50
+ export function createSnapshotFetch(snapshotsDir, testName) {
51
+ const snapshotPath = join(snapshotsDir, `${testName}.json`);
52
+ return async (input, init) => {
53
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
54
+ const method = init?.method ?? 'GET';
55
+ const body = typeof init?.body === 'string' ? init.body : '';
56
+ const currentHash = hashRequest(url, method, body);
57
+ // Try loading existing snapshot
58
+ let snapshot = null;
59
+ try {
60
+ const content = await readFile(snapshotPath, 'utf-8');
61
+ snapshot = JSON.parse(content);
62
+ }
63
+ catch {
64
+ // No snapshot yet
65
+ }
66
+ // If snapshot exists and hash matches, return cached response
67
+ if (snapshot && snapshot.requestHash === currentHash) {
68
+ return new Response(JSON.stringify(snapshot.response.body), {
69
+ status: snapshot.response.status,
70
+ headers: snapshot.response.headers,
71
+ });
72
+ }
73
+ // Make real request
74
+ const response = await globalThis.fetch(input, init);
75
+ const responseBody = await response.json();
76
+ // Extract response headers
77
+ const responseHeaders = {};
78
+ response.headers.forEach((value, key) => {
79
+ responseHeaders[key] = value;
80
+ });
81
+ // Extract request headers
82
+ const requestHeaders = {};
83
+ if (init?.headers) {
84
+ if (init.headers instanceof Headers) {
85
+ init.headers.forEach((value, key) => {
86
+ requestHeaders[key] = value;
87
+ });
88
+ }
89
+ else if (Array.isArray(init.headers)) {
90
+ for (const [key, value] of init.headers) {
91
+ requestHeaders[key] = value;
92
+ }
93
+ }
94
+ else {
95
+ Object.assign(requestHeaders, init.headers);
96
+ }
97
+ }
98
+ // Save snapshot
99
+ const entry = {
100
+ requestHash: currentHash,
101
+ request: {
102
+ url,
103
+ method,
104
+ headers: sanitizeHeaders(requestHeaders),
105
+ body: body ? JSON.parse(body) : null,
106
+ },
107
+ response: {
108
+ status: response.status,
109
+ headers: sanitizeHeaders(responseHeaders),
110
+ body: responseBody,
111
+ },
112
+ };
113
+ await mkdir(snapshotsDir, { recursive: true });
114
+ await writeFile(snapshotPath, JSON.stringify(entry, null, '\t'));
115
+ // Return a new Response from the parsed body (original was consumed)
116
+ return new Response(JSON.stringify(responseBody), {
117
+ status: response.status,
118
+ headers: responseHeaders,
119
+ });
120
+ };
121
+ }
122
+ //# sourceMappingURL=snapshot-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-fetch.js","sourceRoot":"","sources":["../../../src/core/llm/snapshot-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Snapshot-caching LLM middleware for e2e tests.
3
+ *
4
+ * Works at the InferenceRequest/InferenceResponse boundary (not HTTP). On a
5
+ * request hit, returns the cached response without calling the downstream
6
+ * provider. On a miss, forwards the request, records the response, writes
7
+ * one snapshot file per request hash.
8
+ *
9
+ * Unlike the lower-level `snapshot-fetch` (which writes one file per testName
10
+ * and overwrites on each call), this middleware keys by request hash — so a
11
+ * single multi-turn test records N independent snapshots.
12
+ *
13
+ * Usage:
14
+ * startStandaloneServer({
15
+ * presets: [myPreset],
16
+ * llmMiddleware: [createSnapshotLLMMiddleware({ snapshotsDir: '...' })],
17
+ * })
18
+ */
19
+ import { createHash } from 'node:crypto';
20
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
21
+ import { join } from 'node:path';
22
+ import { Err, Ok } from '../../lib/utils/result.js';
23
+ /**
24
+ * Replace all UUIDs in a string with a `__UUID__` placeholder.
25
+ */
26
+ export function stripUuids(text) {
27
+ return text.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g, '__UUID__');
28
+ }
29
+ /**
30
+ * Replace dynamically assigned TCP ports (e.g. `port 46140`, `:46140`) with
31
+ * a `__PORT__` placeholder. Dev services in roj pick free ports at runtime,
32
+ * which otherwise bust the snapshot key on every run.
33
+ */
34
+ export function stripEphemeralPorts(text) {
35
+ return text
36
+ .replace(/port\s+(\d{4,5})\b/gi, 'port __PORT__')
37
+ .replace(/:(1[0-9]{4}|[2-6][0-9]{4})\b/g, ':__PORT__');
38
+ }
39
+ /**
40
+ * Compose multiple text stripping functions.
41
+ */
42
+ export function composeStrippers(...fns) {
43
+ return (text) => fns.reduce((acc, fn) => fn(acc), text);
44
+ }
45
+ /**
46
+ * Build a `normalize` hook that applies a text-level stripper to the system
47
+ * prompt and all string-form message content / text parts.
48
+ */
49
+ export function normalizeWith(stripper) {
50
+ return (request) => ({
51
+ ...request,
52
+ systemPrompt: stripper(request.systemPrompt),
53
+ messages: request.messages.map((m) => {
54
+ if (typeof m.content === 'string') {
55
+ return { ...m, content: stripper(m.content) };
56
+ }
57
+ if (Array.isArray(m.content)) {
58
+ return {
59
+ ...m,
60
+ content: m.content.map((part) => part.type === 'text' ? { ...part, text: stripper(part.text) } : part),
61
+ };
62
+ }
63
+ return m;
64
+ }),
65
+ });
66
+ }
67
+ /**
68
+ * A `normalize` implementation that strips UUIDs from the request text.
69
+ * Use `normalizeStripRuntime` if dev service ports also leak into prompts.
70
+ */
71
+ export const normalizeStripUuids = normalizeWith(stripUuids);
72
+ /**
73
+ * `normalize` implementation for typical e2e runs: strips UUIDs and
74
+ * dynamically-assigned ports. Covers the usual suspects; add your own with
75
+ * `normalizeWith(composeStrippers(...))` for more.
76
+ */
77
+ export const normalizeStripRuntime = normalizeWith(composeStrippers(stripUuids, stripEphemeralPorts));
78
+ function stableStringify(value) {
79
+ return JSON.stringify(value, (_key, val) => {
80
+ if (val && typeof val === 'object' && !Array.isArray(val)) {
81
+ return Object.fromEntries(Object.entries(val).sort(([a], [b]) => a.localeCompare(b)));
82
+ }
83
+ return val;
84
+ });
85
+ }
86
+ /**
87
+ * Build a stable digest of the request. Strips:
88
+ * - tool `input`/`execute` functions + Zod schemas (reduced to name/description)
89
+ * - conversation-metadata fields on messages (`timestamp`, `isError`,
90
+ * `toolName`, `sourceMessageIds`) — not forwarded to the LLM, so they
91
+ * shouldn't bust the snapshot key either.
92
+ */
93
+ function stripMessageMetadata(message) {
94
+ if (!message || typeof message !== 'object')
95
+ return message;
96
+ const { timestamp: _t, isError: _e, toolName: _n, sourceMessageIds: _s, ...rest } = message;
97
+ return rest;
98
+ }
99
+ function buildDigest(request) {
100
+ return {
101
+ model: String(request.model),
102
+ systemPrompt: request.systemPrompt,
103
+ messages: request.messages.map(stripMessageMetadata),
104
+ tools: request.tools?.map((t) => ({ name: t.name, description: t.description })),
105
+ maxTokens: request.maxTokens,
106
+ temperature: request.temperature,
107
+ stopSequences: request.stopSequences,
108
+ openrouter: request.openrouter,
109
+ anthropic: request.anthropic,
110
+ };
111
+ }
112
+ function hashDigest(digest) {
113
+ return createHash('sha256').update(stableStringify(digest)).digest('hex').slice(0, 16);
114
+ }
115
+ export function createSnapshotLLMMiddleware(options) {
116
+ const mode = options.mode ?? 'auto';
117
+ mkdirSync(options.snapshotsDir, { recursive: true });
118
+ return async (request, context, next) => {
119
+ const forHashing = options.normalize ? options.normalize(request) : request;
120
+ const digest = buildDigest(forHashing);
121
+ const hash = hashDigest(digest);
122
+ const filePath = join(options.snapshotsDir, `${hash}.json`);
123
+ const hasSnapshot = existsSync(filePath);
124
+ if (mode !== 'record' && hasSnapshot) {
125
+ const entry = JSON.parse(readFileSync(filePath, 'utf-8'));
126
+ return Ok(entry.response);
127
+ }
128
+ if (mode === 'replay') {
129
+ return Err({
130
+ type: 'invalid_request',
131
+ message: `Snapshot not found (replay mode): ${hash}. Set mode to 'auto' or 'record' and provide API keys to record.`,
132
+ });
133
+ }
134
+ const result = await next(request, context);
135
+ if (result.ok) {
136
+ const entry = { request: digest, response: result.value };
137
+ writeFileSync(filePath, JSON.stringify(entry, null, '\t'));
138
+ }
139
+ return result;
140
+ };
141
+ }
142
+ //# sourceMappingURL=snapshot-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-middleware.js","sourceRoot":"","sources":["../../../src/core/llm/snapshot-middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
2
+ import { mkdtempSync, readdirSync, rmSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { isErr, isOk } from '../../lib/utils/result.js';
6
+ import { applyMiddleware } from './middleware.js';
7
+ import { MockLLMProvider } from './mock.js';
8
+ import { ModelId } from './schema.js';
9
+ import { createSnapshotLLMMiddleware } from './snapshot-middleware.js';
10
+ describe('SnapshotLLMMiddleware', () => {
11
+ let dir;
12
+ beforeEach(() => {
13
+ dir = mkdtempSync(join(tmpdir(), 'roj-snap-'));
14
+ });
15
+ afterEach(() => {
16
+ rmSync(dir, { recursive: true, force: true });
17
+ });
18
+ const request = (overrides = {}) => ({
19
+ model: ModelId('test-model'),
20
+ systemPrompt: 'You are a test assistant.',
21
+ messages: [{ role: 'user', content: 'Hello' }],
22
+ ...overrides,
23
+ });
24
+ const fixedResponse = {
25
+ content: 'Recorded response',
26
+ toolCalls: [],
27
+ finishReason: 'stop',
28
+ metrics: MockLLMProvider.defaultMetrics(),
29
+ };
30
+ test('records on miss and replays on hit without calling next', async () => {
31
+ const downstream = new MockLLMProvider(() => fixedResponse);
32
+ const wrapped = applyMiddleware(downstream, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
33
+ const first = await wrapped.inference(request());
34
+ expect(isOk(first)).toBe(true);
35
+ expect(downstream.getCallCount()).toBe(1);
36
+ // Snapshot file created
37
+ const files = readdirSync(dir);
38
+ expect(files.length).toBe(1);
39
+ expect(files[0]).toMatch(/^[0-9a-f]{16}\.json$/);
40
+ // Replay — downstream NOT called again
41
+ const second = await wrapped.inference(request());
42
+ expect(isOk(second)).toBe(true);
43
+ if (isOk(second)) {
44
+ expect(second.value.content).toBe('Recorded response');
45
+ }
46
+ expect(downstream.getCallCount()).toBe(1);
47
+ });
48
+ test('distinct requests produce distinct snapshot files', async () => {
49
+ const downstream = new MockLLMProvider(() => fixedResponse);
50
+ const wrapped = applyMiddleware(downstream, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
51
+ await wrapped.inference(request({ messages: [{ role: 'user', content: 'A' }] }));
52
+ await wrapped.inference(request({ messages: [{ role: 'user', content: 'B' }] }));
53
+ expect(readdirSync(dir).length).toBe(2);
54
+ expect(downstream.getCallCount()).toBe(2);
55
+ });
56
+ test('hash is stable across key-order differences', async () => {
57
+ const downstream = new MockLLMProvider(() => fixedResponse);
58
+ const wrapped = applyMiddleware(downstream, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
59
+ // Two requests identical in content but constructed with different key order
60
+ await wrapped.inference({
61
+ model: ModelId('m'),
62
+ systemPrompt: 's',
63
+ messages: [{ role: 'user', content: 'x' }],
64
+ temperature: 0.5,
65
+ maxTokens: 100,
66
+ });
67
+ await wrapped.inference({
68
+ maxTokens: 100,
69
+ temperature: 0.5,
70
+ messages: [{ role: 'user', content: 'x' }],
71
+ systemPrompt: 's',
72
+ model: ModelId('m'),
73
+ });
74
+ // Same hash → single snapshot file → downstream called once
75
+ expect(readdirSync(dir).length).toBe(1);
76
+ expect(downstream.getCallCount()).toBe(1);
77
+ });
78
+ test('replay mode errors on miss', async () => {
79
+ const downstream = new MockLLMProvider(() => fixedResponse);
80
+ const wrapped = applyMiddleware(downstream, [
81
+ createSnapshotLLMMiddleware({ snapshotsDir: dir, mode: 'replay' }),
82
+ ]);
83
+ const result = await wrapped.inference(request());
84
+ expect(isErr(result)).toBe(true);
85
+ if (isErr(result)) {
86
+ expect(result.error.type).toBe('invalid_request');
87
+ expect(result.error.message).toContain('Snapshot not found');
88
+ }
89
+ expect(downstream.getCallCount()).toBe(0);
90
+ });
91
+ test('replay mode serves existing snapshot', async () => {
92
+ // Pre-seed a snapshot by running once in auto mode
93
+ const downstream1 = new MockLLMProvider(() => fixedResponse);
94
+ const recording = applyMiddleware(downstream1, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
95
+ await recording.inference(request());
96
+ // Now a replay-only chain must hit it
97
+ const downstream2 = new MockLLMProvider(() => {
98
+ throw new Error('should not be called');
99
+ });
100
+ const replaying = applyMiddleware(downstream2, [
101
+ createSnapshotLLMMiddleware({ snapshotsDir: dir, mode: 'replay' }),
102
+ ]);
103
+ const result = await replaying.inference(request());
104
+ expect(isOk(result)).toBe(true);
105
+ if (isOk(result)) {
106
+ expect(result.value.content).toBe('Recorded response');
107
+ }
108
+ });
109
+ test('record mode overwrites existing snapshot', async () => {
110
+ // Seed with response A
111
+ const downstream1 = new MockLLMProvider(() => ({ ...fixedResponse, content: 'A' }));
112
+ const first = applyMiddleware(downstream1, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
113
+ await first.inference(request());
114
+ // Force re-record with response B
115
+ const downstream2 = new MockLLMProvider(() => ({ ...fixedResponse, content: 'B' }));
116
+ const second = applyMiddleware(downstream2, [
117
+ createSnapshotLLMMiddleware({ snapshotsDir: dir, mode: 'record' }),
118
+ ]);
119
+ await second.inference(request());
120
+ // Read back
121
+ const downstream3 = new MockLLMProvider(() => {
122
+ throw new Error('should not be called');
123
+ });
124
+ const third = applyMiddleware(downstream3, [
125
+ createSnapshotLLMMiddleware({ snapshotsDir: dir, mode: 'replay' }),
126
+ ]);
127
+ const result = await third.inference(request());
128
+ expect(isOk(result)).toBe(true);
129
+ if (isOk(result)) {
130
+ expect(result.value.content).toBe('B');
131
+ }
132
+ });
133
+ test('does not persist error responses', async () => {
134
+ const downstream = new MockLLMProvider(() => {
135
+ const err = { type: 'rate_limit', message: 'throttled' };
136
+ throw err;
137
+ });
138
+ const wrapped = applyMiddleware(downstream, [createSnapshotLLMMiddleware({ snapshotsDir: dir })]);
139
+ const result = await wrapped.inference(request());
140
+ expect(isErr(result)).toBe(true);
141
+ expect(readdirSync(dir).length).toBe(0);
142
+ });
143
+ });
144
+ //# sourceMappingURL=snapshot-middleware.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-middleware.test.js","sourceRoot":"","sources":["../../../src/core/llm/snapshot-middleware.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import z4 from 'zod/v4';
2
+ import { agentIdSchema } from '../../core/agents';
3
+ import { createEventsFactory } from '../../core/events/types';
4
+ import { toolCallIdSchema } from '../../core/tools/schema';
5
+ import { messageIdSchema } from '../../plugins/mailbox/schema';
6
+ import { llmCallIdSchema } from './schema';
7
+ // ============================================================================
8
+ // LLM events
9
+ // ============================================================================
10
+ export const llmEvents = createEventsFactory({
11
+ events: {
12
+ inference_started: z4.object({
13
+ agentId: agentIdSchema,
14
+ messages: z4.array(z4.custom()),
15
+ consumedMessageIds: z4.array(messageIdSchema),
16
+ }),
17
+ inference_completed: z4.object({
18
+ agentId: agentIdSchema,
19
+ consumedMessageIds: z4.array(messageIdSchema),
20
+ response: z4.object({
21
+ content: z4.string().nullable(),
22
+ toolCalls: z4.array(z4.object({
23
+ id: toolCallIdSchema,
24
+ name: z4.string(),
25
+ input: z4.unknown(),
26
+ })),
27
+ }),
28
+ metrics: z4.object({
29
+ promptTokens: z4.number(),
30
+ completionTokens: z4.number(),
31
+ totalTokens: z4.number(),
32
+ latencyMs: z4.number(),
33
+ model: z4.string(),
34
+ provider: z4.string().optional(),
35
+ cost: z4.number().optional(),
36
+ cachedTokens: z4.number().optional(),
37
+ cacheWriteTokens: z4.number().optional(),
38
+ }),
39
+ llmCallId: llmCallIdSchema.optional(),
40
+ }),
41
+ inference_failed: z4.object({
42
+ agentId: agentIdSchema,
43
+ error: z4.string(),
44
+ llmCallId: llmCallIdSchema.optional(),
45
+ }),
46
+ },
47
+ });
48
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/llm/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,QAAQ,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAwC1C,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,MAAM,CAAC,MAAM,SAAS,GAAG,mBAAmB,CAAC;IAC5C,MAAM,EAAE;QACP,iBAAiB,EAAE,EAAE,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,aAAa;YACtB,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAc,CAAC;YAC3C,kBAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC;SAC7C,CAAC;QACF,mBAAmB,EAAE,EAAE,CAAC,MAAM,CAAC;YAC9B,OAAO,EAAE,aAAa;YACtB,kBAAkB,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC;YAC7C,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC;gBACnB,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC/B,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;oBAC7B,EAAE,EAAE,gBAAgB;oBACpB,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE;oBACjB,KAAK,EAAE,EAAE,CAAC,OAAO,EAAE;iBACnB,CAAC,CAAC;aACH,CAAC;YACF,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC;gBAClB,YAAY,EAAE,EAAE,CAAC,MAAM,EAAE;gBACzB,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE;gBAC7B,WAAW,EAAE,EAAE,CAAC,MAAM,EAAE;gBACxB,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE;gBACtB,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE;gBAClB,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAChC,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC5B,YAAY,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBACpC,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aACxC,CAAC;YACF,SAAS,EAAE,eAAe,CAAC,QAAQ,EAAE;SACrC,CAAC;QACF,gBAAgB,EAAE,EAAE,CAAC,MAAM,CAAC;YAC3B,OAAO,EAAE,aAAa;YACtB,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE;YAClB,SAAS,EAAE,eAAe,CAAC,QAAQ,EAAE;SACrC,CAAC;KACF;CACD,CAAC,CAAA"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Token estimation utilities using tokenx library.
3
+ * Provides ~95-98% accuracy compared to full tokenizers.
4
+ */
5
+ import { estimateTokenCount, sliceByTokens } from 'tokenx';
6
+ /**
7
+ * Estimate token count for a text string.
8
+ * Uses tokenx library for better accuracy than simple char/4 heuristic.
9
+ */
10
+ export function estimateTokens(text) {
11
+ return estimateTokenCount(text);
12
+ }
13
+ /**
14
+ * Truncate text to fit within a token budget.
15
+ * Returns null if text is already within budget.
16
+ * Uses 80/20 head/tail split via sliceByTokens.
17
+ */
18
+ export function truncateByTokens(text, maxTokens) {
19
+ const originalTokens = estimateTokenCount(text);
20
+ // 5% tolerance to avoid truncating near the boundary
21
+ if (originalTokens <= maxTokens * 1.05)
22
+ return null;
23
+ const headBudget = Math.floor(maxTokens * 0.8);
24
+ const tailBudget = maxTokens - headBudget;
25
+ const head = sliceByTokens(text, 0, headBudget);
26
+ const tail = sliceByTokens(text, -tailBudget);
27
+ const content = `${head}\n\n[... truncated — ~${originalTokens} tokens total ...]\n\n${tail}`;
28
+ return { content, originalTokens };
29
+ }
30
+ /**
31
+ * Estimate total tokens for an array of messages.
32
+ * Includes ~4 tokens overhead per message for role/formatting.
33
+ */
34
+ export function estimateMessagesTokens(messages) {
35
+ return messages.reduce((sum, msg) => {
36
+ const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
37
+ return sum + estimateTokens(content) + 4; // 4 tokens overhead per message
38
+ }, 0);
39
+ }
40
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/core/llm/tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAE1D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC;AAmBD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IAC/D,MAAM,cAAc,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAC/C,qDAAqD;IACrD,IAAI,cAAc,IAAI,SAAS,GAAG,IAAI;QAAE,OAAO,IAAI,CAAA;IAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IACzC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAA;IAE7C,MAAM,OAAO,GAAG,GAAG,IAAI,yBAAyB,cAAc,yBAAyB,IAAI,EAAE,CAAA;IAC7F,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAA;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAkC;IACxE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC3F,OAAO,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA,CAAC,gCAAgC;IAC1E,CAAC,EAAE,CAAC,CAAC,CAAA;AACN,CAAC"}