@theowlops/boombot 0.0.0-stage → 1.1.0

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 (544) hide show
  1. package/README.md +69 -3
  2. package/dist/LICENSE +21 -0
  3. package/dist/bin/boombot.js +16 -0
  4. package/dist/cli/api-key.js +123 -0
  5. package/dist/cli/bin-bun.js +17 -0
  6. package/dist/cli/bin.js +34 -0
  7. package/dist/cli/cli/cli-error.js +61 -0
  8. package/dist/cli/cli/dispatch.js +138 -0
  9. package/dist/cli/cli/help.js +83 -0
  10. package/dist/cli/cli/parser.js +89 -0
  11. package/dist/cli/cli/registry.js +185 -0
  12. package/dist/cli/cli/spec.js +41 -0
  13. package/dist/cli/cli/suggest.js +125 -0
  14. package/dist/cli/cli/version.js +30 -0
  15. package/dist/cli/cli/vocabulary.js +87 -0
  16. package/dist/cli/commands/doctor.js +365 -0
  17. package/dist/cli/commands/gateway.js +290 -0
  18. package/dist/cli/commands/migrate.js +270 -0
  19. package/dist/cli/commands/plugin.js +97 -0
  20. package/dist/cli/commands/setup.js +230 -0
  21. package/dist/cli/config-file.js +133 -0
  22. package/dist/cli/master-key.js +78 -0
  23. package/dist/cli/open-browser.js +59 -0
  24. package/dist/cli/web-assets.js +58 -0
  25. package/dist/gateway/auth.js +46 -0
  26. package/dist/gateway/config-format.js +202 -0
  27. package/dist/gateway/config.js +427 -0
  28. package/dist/gateway/context.js +1 -0
  29. package/dist/gateway/env-file.js +129 -0
  30. package/dist/gateway/events.js +172 -0
  31. package/dist/gateway/guard/tagging.js +505 -0
  32. package/dist/gateway/handlers/index.js +66 -0
  33. package/dist/gateway/handlers/memory.js +54 -0
  34. package/dist/gateway/handlers/providers.js +73 -0
  35. package/dist/gateway/handlers/registry.js +39 -0
  36. package/dist/gateway/handlers/sessions.js +188 -0
  37. package/dist/gateway/handlers/system.js +12 -0
  38. package/dist/gateway/handlers/tasks.js +191 -0
  39. package/dist/gateway/handlers/turn.js +100 -0
  40. package/dist/gateway/index.js +126 -0
  41. package/dist/gateway/main.js +23 -0
  42. package/dist/gateway/server.js +354 -0
  43. package/dist/gateway/services/context-limits.js +75 -0
  44. package/dist/gateway/services/history-normalizer.js +42 -0
  45. package/dist/gateway/services/image-pipeline.js +56 -0
  46. package/dist/gateway/services/key-roulette-client.js +43 -0
  47. package/dist/gateway/services/llm-client.js +593 -0
  48. package/dist/gateway/services/llm-decoder.js +200 -0
  49. package/dist/gateway/services/local-fallback.js +135 -0
  50. package/dist/gateway/services/memory.js +511 -0
  51. package/dist/gateway/services/persistent-memory.js +196 -0
  52. package/dist/gateway/services/providers.js +44 -0
  53. package/dist/gateway/services/tasks.js +237 -0
  54. package/dist/gateway/services/verification.js +124 -0
  55. package/dist/gateway/services/vision-payload.js +48 -0
  56. package/dist/gateway/services.js +257 -0
  57. package/dist/gateway/session-snapshot.js +19 -0
  58. package/dist/gateway/sessions.js +701 -0
  59. package/dist/gateway/static.js +239 -0
  60. package/dist/gateway/turns/clarify-tool.js +57 -0
  61. package/dist/gateway/turns/cronjob-tool.js +96 -0
  62. package/dist/gateway/turns/deferred-tools.js +154 -0
  63. package/dist/gateway/turns/execute-code-tool.js +84 -0
  64. package/dist/gateway/turns/file-tool-defs.js +178 -0
  65. package/dist/gateway/turns/file-tool-ops.js +178 -0
  66. package/dist/gateway/turns/file-tool-scan.js +182 -0
  67. package/dist/gateway/turns/file-tool.js +302 -0
  68. package/dist/gateway/turns/index.js +416 -0
  69. package/dist/gateway/turns/jev-middleware.js +91 -0
  70. package/dist/gateway/turns/local-reply.js +156 -0
  71. package/dist/gateway/turns/mcp-client.js +643 -0
  72. package/dist/gateway/turns/memory-tool.js +171 -0
  73. package/dist/gateway/turns/middleware.js +96 -0
  74. package/dist/gateway/turns/python-core.js +397 -0
  75. package/dist/gateway/turns/routing/index.js +3 -0
  76. package/dist/gateway/turns/routing/intent-classifier.js +60 -0
  77. package/dist/gateway/turns/routing/planner-adapter.js +91 -0
  78. package/dist/gateway/turns/routing/types.js +1 -0
  79. package/dist/gateway/turns/runtime-deps.js +228 -0
  80. package/dist/gateway/turns/self-config-tool.js +277 -0
  81. package/dist/gateway/turns/service-types.js +11 -0
  82. package/dist/gateway/turns/service.js +820 -0
  83. package/dist/gateway/turns/session-adapter.js +158 -0
  84. package/dist/gateway/turns/session-tool.js +49 -0
  85. package/dist/gateway/turns/shell-tool.js +190 -0
  86. package/dist/gateway/turns/skill-tool.js +239 -0
  87. package/dist/gateway/turns/spillover.js +201 -0
  88. package/dist/gateway/turns/subagent-tool.js +140 -0
  89. package/dist/gateway/turns/system-prompt.js +121 -0
  90. package/dist/gateway/turns/tool-schema.js +90 -0
  91. package/dist/gateway/turns/turn-utils.js +58 -0
  92. package/dist/gateway/turns/vision-tool.js +120 -0
  93. package/dist/gateway/types.js +1 -0
  94. package/dist/native/win32-x64/boombot-native-host.exe +0 -0
  95. package/dist/node_modules/@boombot/channels/handlers.d.ts +9 -0
  96. package/dist/node_modules/@boombot/channels/handlers.js +109 -0
  97. package/dist/node_modules/@boombot/channels/index.d.ts +12 -0
  98. package/dist/node_modules/@boombot/channels/index.js +12 -0
  99. package/dist/node_modules/@boombot/channels/package.json +9 -0
  100. package/dist/node_modules/@boombot/channels/service.d.ts +62 -0
  101. package/dist/node_modules/@boombot/channels/service.js +608 -0
  102. package/dist/node_modules/@boombot/channels/tool.d.ts +10 -0
  103. package/dist/node_modules/@boombot/channels/tool.js +46 -0
  104. package/dist/node_modules/@boombot/channels/transports/common/dedup.d.ts +17 -0
  105. package/dist/node_modules/@boombot/channels/transports/common/dedup.js +42 -0
  106. package/dist/node_modules/@boombot/channels/transports/common/handoff.d.ts +19 -0
  107. package/dist/node_modules/@boombot/channels/transports/common/handoff.js +32 -0
  108. package/dist/node_modules/@boombot/channels/transports/common/index.d.ts +3 -0
  109. package/dist/node_modules/@boombot/channels/transports/common/index.js +3 -0
  110. package/dist/node_modules/@boombot/channels/transports/common/types.d.ts +99 -0
  111. package/dist/node_modules/@boombot/channels/transports/common/types.js +54 -0
  112. package/dist/node_modules/@boombot/channels/transports/common.d.ts +2 -0
  113. package/dist/node_modules/@boombot/channels/transports/common.js +2 -0
  114. package/dist/node_modules/@boombot/channels/transports/dedup/index.d.ts +1 -0
  115. package/dist/node_modules/@boombot/channels/transports/dedup/index.js +1 -0
  116. package/dist/node_modules/@boombot/channels/transports/dedup.d.ts +2 -0
  117. package/dist/node_modules/@boombot/channels/transports/dedup.js +2 -0
  118. package/dist/node_modules/@boombot/channels/transports/discord/index.d.ts +1 -0
  119. package/dist/node_modules/@boombot/channels/transports/discord/index.js +1 -0
  120. package/dist/node_modules/@boombot/channels/transports/discord/transport.d.ts +36 -0
  121. package/dist/node_modules/@boombot/channels/transports/discord/transport.js +199 -0
  122. package/dist/node_modules/@boombot/channels/transports/discord.d.ts +2 -0
  123. package/dist/node_modules/@boombot/channels/transports/discord.js +2 -0
  124. package/dist/node_modules/@boombot/channels/transports/handoff.d.ts +2 -0
  125. package/dist/node_modules/@boombot/channels/transports/handoff.js +2 -0
  126. package/dist/node_modules/@boombot/channels/transports/messenger/index.d.ts +1 -0
  127. package/dist/node_modules/@boombot/channels/transports/messenger/index.js +1 -0
  128. package/dist/node_modules/@boombot/channels/transports/messenger/transport.d.ts +34 -0
  129. package/dist/node_modules/@boombot/channels/transports/messenger/transport.js +180 -0
  130. package/dist/node_modules/@boombot/channels/transports/messenger.d.ts +2 -0
  131. package/dist/node_modules/@boombot/channels/transports/messenger.js +2 -0
  132. package/dist/node_modules/@boombot/channels/transports/slack/index.d.ts +1 -0
  133. package/dist/node_modules/@boombot/channels/transports/slack/index.js +1 -0
  134. package/dist/node_modules/@boombot/channels/transports/slack/transport.d.ts +35 -0
  135. package/dist/node_modules/@boombot/channels/transports/slack/transport.js +183 -0
  136. package/dist/node_modules/@boombot/channels/transports/slack.d.ts +2 -0
  137. package/dist/node_modules/@boombot/channels/transports/slack.js +2 -0
  138. package/dist/node_modules/@boombot/channels/transports/streamer/index.d.ts +1 -0
  139. package/dist/node_modules/@boombot/channels/transports/streamer/index.js +1 -0
  140. package/dist/node_modules/@boombot/channels/transports/streamer/streamer.d.ts +31 -0
  141. package/dist/node_modules/@boombot/channels/transports/streamer/streamer.js +141 -0
  142. package/dist/node_modules/@boombot/channels/transports/streamer.d.ts +2 -0
  143. package/dist/node_modules/@boombot/channels/transports/streamer.js +2 -0
  144. package/dist/node_modules/@boombot/channels/transports/telegram/index.d.ts +1 -0
  145. package/dist/node_modules/@boombot/channels/transports/telegram/index.js +1 -0
  146. package/dist/node_modules/@boombot/channels/transports/telegram/transport.d.ts +75 -0
  147. package/dist/node_modules/@boombot/channels/transports/telegram/transport.js +395 -0
  148. package/dist/node_modules/@boombot/channels/transports/telegram.d.ts +2 -0
  149. package/dist/node_modules/@boombot/channels/transports/telegram.js +2 -0
  150. package/dist/node_modules/@boombot/channels/transports/tiktok/index.d.ts +1 -0
  151. package/dist/node_modules/@boombot/channels/transports/tiktok/index.js +1 -0
  152. package/dist/node_modules/@boombot/channels/transports/tiktok/transport.d.ts +27 -0
  153. package/dist/node_modules/@boombot/channels/transports/tiktok/transport.js +97 -0
  154. package/dist/node_modules/@boombot/channels/transports/tiktok.d.ts +2 -0
  155. package/dist/node_modules/@boombot/channels/transports/tiktok.js +2 -0
  156. package/dist/node_modules/@boombot/channels/transports/whatsapp/index.d.ts +1 -0
  157. package/dist/node_modules/@boombot/channels/transports/whatsapp/index.js +1 -0
  158. package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.d.ts +38 -0
  159. package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.js +189 -0
  160. package/dist/node_modules/@boombot/channels/transports/whatsapp.d.ts +2 -0
  161. package/dist/node_modules/@boombot/channels/transports/whatsapp.js +2 -0
  162. package/dist/node_modules/@boombot/channels/transports/zalo/index.d.ts +2 -0
  163. package/dist/node_modules/@boombot/channels/transports/zalo/index.js +2 -0
  164. package/dist/node_modules/@boombot/channels/transports/zalo/oa.d.ts +28 -0
  165. package/dist/node_modules/@boombot/channels/transports/zalo/oa.js +94 -0
  166. package/dist/node_modules/@boombot/channels/transports/zalo/personal.d.ts +106 -0
  167. package/dist/node_modules/@boombot/channels/transports/zalo/personal.js +171 -0
  168. package/dist/node_modules/@boombot/channels/transports/zalo-personal.d.ts +2 -0
  169. package/dist/node_modules/@boombot/channels/transports/zalo-personal.js +2 -0
  170. package/dist/node_modules/@boombot/channels/transports/zalo.d.ts +2 -0
  171. package/dist/node_modules/@boombot/channels/transports/zalo.js +2 -0
  172. package/dist/node_modules/@boombot/core/agent-core/index.d.ts +12 -0
  173. package/dist/node_modules/@boombot/core/agent-core/index.js +12 -0
  174. package/dist/node_modules/@boombot/core/agent-core/middleware.d.ts +60 -0
  175. package/dist/node_modules/@boombot/core/agent-core/middleware.js +152 -0
  176. package/dist/node_modules/@boombot/core/agent-core/routing.d.ts +128 -0
  177. package/dist/node_modules/@boombot/core/agent-core/routing.js +437 -0
  178. package/dist/node_modules/@boombot/core/agent-core/runtime-deps.d.ts +88 -0
  179. package/dist/node_modules/@boombot/core/agent-core/runtime-deps.js +8 -0
  180. package/dist/node_modules/@boombot/core/agent-core/tool-errors.d.ts +44 -0
  181. package/dist/node_modules/@boombot/core/agent-core/tool-errors.js +60 -0
  182. package/dist/node_modules/@boombot/core/agent-core/turn-loop.d.ts +21 -0
  183. package/dist/node_modules/@boombot/core/agent-core/turn-loop.js +561 -0
  184. package/dist/node_modules/@boombot/core/agent-core/types.d.ts +189 -0
  185. package/dist/node_modules/@boombot/core/agent-core/types.js +7 -0
  186. package/dist/node_modules/@boombot/core/compaction/compactor.d.ts +19 -0
  187. package/dist/node_modules/@boombot/core/compaction/compactor.js +127 -0
  188. package/dist/node_modules/@boombot/core/compaction/estimator.d.ts +10 -0
  189. package/dist/node_modules/@boombot/core/compaction/estimator.js +48 -0
  190. package/dist/node_modules/@boombot/core/compaction/index.d.ts +3 -0
  191. package/dist/node_modules/@boombot/core/compaction/index.js +3 -0
  192. package/dist/node_modules/@boombot/core/compaction/types.d.ts +31 -0
  193. package/dist/node_modules/@boombot/core/compaction/types.js +7 -0
  194. package/dist/node_modules/@boombot/core/index.d.ts +9 -0
  195. package/dist/node_modules/@boombot/core/index.js +9 -0
  196. package/dist/node_modules/@boombot/core/jev/index.d.ts +2 -0
  197. package/dist/node_modules/@boombot/core/jev/index.js +2 -0
  198. package/dist/node_modules/@boombot/core/jev/jev.d.ts +30 -0
  199. package/dist/node_modules/@boombot/core/jev/jev.js +164 -0
  200. package/dist/node_modules/@boombot/core/jev/types.d.ts +22 -0
  201. package/dist/node_modules/@boombot/core/jev/types.js +1 -0
  202. package/dist/node_modules/@boombot/core/memory/consolidation/budget.d.ts +63 -0
  203. package/dist/node_modules/@boombot/core/memory/consolidation/budget.js +94 -0
  204. package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.d.ts +152 -0
  205. package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.js +318 -0
  206. package/dist/node_modules/@boombot/core/memory/consolidation/index.d.ts +12 -0
  207. package/dist/node_modules/@boombot/core/memory/consolidation/index.js +12 -0
  208. package/dist/node_modules/@boombot/core/memory/curation.d.ts +86 -0
  209. package/dist/node_modules/@boombot/core/memory/curation.js +120 -0
  210. package/dist/node_modules/@boombot/core/memory/errors.d.ts +12 -0
  211. package/dist/node_modules/@boombot/core/memory/errors.js +20 -0
  212. package/dist/node_modules/@boombot/core/memory/hybrid-search.d.ts +29 -0
  213. package/dist/node_modules/@boombot/core/memory/hybrid-search.js +52 -0
  214. package/dist/node_modules/@boombot/core/memory/index.d.ts +23 -0
  215. package/dist/node_modules/@boombot/core/memory/index.js +23 -0
  216. package/dist/node_modules/@boombot/core/memory/indexer.d.ts +47 -0
  217. package/dist/node_modules/@boombot/core/memory/indexer.js +138 -0
  218. package/dist/node_modules/@boombot/core/memory/lifecycle.d.ts +12 -0
  219. package/dist/node_modules/@boombot/core/memory/lifecycle.js +66 -0
  220. package/dist/node_modules/@boombot/core/memory/provider.d.ts +84 -0
  221. package/dist/node_modules/@boombot/core/memory/provider.js +117 -0
  222. package/dist/node_modules/@boombot/core/memory/recall.d.ts +7 -0
  223. package/dist/node_modules/@boombot/core/memory/recall.js +111 -0
  224. package/dist/node_modules/@boombot/core/memory/scope-resolver.d.ts +27 -0
  225. package/dist/node_modules/@boombot/core/memory/scope-resolver.js +60 -0
  226. package/dist/node_modules/@boombot/core/memory/search.d.ts +37 -0
  227. package/dist/node_modules/@boombot/core/memory/search.js +158 -0
  228. package/dist/node_modules/@boombot/core/memory/store.d.ts +60 -0
  229. package/dist/node_modules/@boombot/core/memory/store.js +289 -0
  230. package/dist/node_modules/@boombot/core/memory/types.d.ts +121 -0
  231. package/dist/node_modules/@boombot/core/memory/types.js +21 -0
  232. package/dist/node_modules/@boombot/core/memory/vector-index.d.ts +34 -0
  233. package/dist/node_modules/@boombot/core/memory/vector-index.js +65 -0
  234. package/dist/node_modules/@boombot/core/package.json +9 -0
  235. package/dist/node_modules/@boombot/core/reflection/classifier.d.ts +13 -0
  236. package/dist/node_modules/@boombot/core/reflection/classifier.js +77 -0
  237. package/dist/node_modules/@boombot/core/reflection/index.d.ts +2 -0
  238. package/dist/node_modules/@boombot/core/reflection/index.js +2 -0
  239. package/dist/node_modules/@boombot/core/reflection/types.d.ts +13 -0
  240. package/dist/node_modules/@boombot/core/reflection/types.js +4 -0
  241. package/dist/node_modules/@boombot/core/research/config.d.ts +89 -0
  242. package/dist/node_modules/@boombot/core/research/config.js +206 -0
  243. package/dist/node_modules/@boombot/core/research/crawl.d.ts +36 -0
  244. package/dist/node_modules/@boombot/core/research/crawl.js +179 -0
  245. package/dist/node_modules/@boombot/core/research/factory.d.ts +26 -0
  246. package/dist/node_modules/@boombot/core/research/factory.js +46 -0
  247. package/dist/node_modules/@boombot/core/research/http.d.ts +87 -0
  248. package/dist/node_modules/@boombot/core/research/http.js +250 -0
  249. package/dist/node_modules/@boombot/core/research/index.d.ts +17 -0
  250. package/dist/node_modules/@boombot/core/research/index.js +10 -0
  251. package/dist/node_modules/@boombot/core/research/orchestrator.d.ts +113 -0
  252. package/dist/node_modules/@boombot/core/research/orchestrator.js +252 -0
  253. package/dist/node_modules/@boombot/core/research/parse/docx.d.ts +24 -0
  254. package/dist/node_modules/@boombot/core/research/parse/docx.js +183 -0
  255. package/dist/node_modules/@boombot/core/research/parse/guards.d.ts +89 -0
  256. package/dist/node_modules/@boombot/core/research/parse/guards.js +171 -0
  257. package/dist/node_modules/@boombot/core/research/parse/index.d.ts +68 -0
  258. package/dist/node_modules/@boombot/core/research/parse/index.js +219 -0
  259. package/dist/node_modules/@boombot/core/research/parse/pdf.d.ts +38 -0
  260. package/dist/node_modules/@boombot/core/research/parse/pdf.js +567 -0
  261. package/dist/node_modules/@boombot/core/research/providers/arxiv.d.ts +9 -0
  262. package/dist/node_modules/@boombot/core/research/providers/arxiv.js +72 -0
  263. package/dist/node_modules/@boombot/core/research/providers/brave.d.ts +11 -0
  264. package/dist/node_modules/@boombot/core/research/providers/brave.js +36 -0
  265. package/dist/node_modules/@boombot/core/research/providers/duckduckgo.d.ts +9 -0
  266. package/dist/node_modules/@boombot/core/research/providers/duckduckgo.js +78 -0
  267. package/dist/node_modules/@boombot/core/research/providers/exa.d.ts +11 -0
  268. package/dist/node_modules/@boombot/core/research/providers/exa.js +34 -0
  269. package/dist/node_modules/@boombot/core/research/providers/firecrawl.d.ts +16 -0
  270. package/dist/node_modules/@boombot/core/research/providers/firecrawl.js +47 -0
  271. package/dist/node_modules/@boombot/core/research/providers/index.d.ts +17 -0
  272. package/dist/node_modules/@boombot/core/research/providers/index.js +11 -0
  273. package/dist/node_modules/@boombot/core/research/providers/jina.d.ts +13 -0
  274. package/dist/node_modules/@boombot/core/research/providers/jina.js +114 -0
  275. package/dist/node_modules/@boombot/core/research/providers/openalex.d.ts +14 -0
  276. package/dist/node_modules/@boombot/core/research/providers/openalex.js +66 -0
  277. package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.d.ts +9 -0
  278. package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.js +56 -0
  279. package/dist/node_modules/@boombot/core/research/providers/tavily.d.ts +11 -0
  280. package/dist/node_modules/@boombot/core/research/providers/tavily.js +35 -0
  281. package/dist/node_modules/@boombot/core/research/providers/wikipedia.d.ts +12 -0
  282. package/dist/node_modules/@boombot/core/research/providers/wikipedia.js +47 -0
  283. package/dist/node_modules/@boombot/core/research/tools.d.ts +27 -0
  284. package/dist/node_modules/@boombot/core/research/tools.js +251 -0
  285. package/dist/node_modules/@boombot/core/research/types.d.ts +133 -0
  286. package/dist/node_modules/@boombot/core/research/types.js +8 -0
  287. package/dist/node_modules/@boombot/core/research/wiring.d.ts +25 -0
  288. package/dist/node_modules/@boombot/core/research/wiring.js +51 -0
  289. package/dist/node_modules/@boombot/core/scheduler/cron.d.ts +34 -0
  290. package/dist/node_modules/@boombot/core/scheduler/cron.js +147 -0
  291. package/dist/node_modules/@boombot/core/scheduler/evaluator.d.ts +42 -0
  292. package/dist/node_modules/@boombot/core/scheduler/evaluator.js +148 -0
  293. package/dist/node_modules/@boombot/core/scheduler/index.d.ts +15 -0
  294. package/dist/node_modules/@boombot/core/scheduler/index.js +15 -0
  295. package/dist/node_modules/@boombot/core/scheduler/registry.d.ts +81 -0
  296. package/dist/node_modules/@boombot/core/scheduler/registry.js +263 -0
  297. package/dist/node_modules/@boombot/core/scheduler/runner.d.ts +59 -0
  298. package/dist/node_modules/@boombot/core/scheduler/runner.js +257 -0
  299. package/dist/node_modules/@boombot/core/scheduler/store.d.ts +150 -0
  300. package/dist/node_modules/@boombot/core/scheduler/store.js +526 -0
  301. package/dist/node_modules/@boombot/core/scheduler/timezone.d.ts +35 -0
  302. package/dist/node_modules/@boombot/core/scheduler/timezone.js +96 -0
  303. package/dist/node_modules/@boombot/core/scheduler/types.d.ts +157 -0
  304. package/dist/node_modules/@boombot/core/scheduler/types.js +89 -0
  305. package/dist/node_modules/@boombot/core/task-runner/index.d.ts +7 -0
  306. package/dist/node_modules/@boombot/core/task-runner/index.js +5 -0
  307. package/dist/node_modules/@boombot/core/task-runner/planner.d.ts +37 -0
  308. package/dist/node_modules/@boombot/core/task-runner/planner.js +154 -0
  309. package/dist/node_modules/@boombot/core/task-runner/runner.d.ts +8 -0
  310. package/dist/node_modules/@boombot/core/task-runner/runner.js +564 -0
  311. package/dist/node_modules/@boombot/core/task-runner/store.d.ts +28 -0
  312. package/dist/node_modules/@boombot/core/task-runner/store.js +126 -0
  313. package/dist/node_modules/@boombot/core/task-runner/types.d.ts +138 -0
  314. package/dist/node_modules/@boombot/core/task-runner/types.js +11 -0
  315. package/dist/node_modules/@boombot/core/workflow/dag.d.ts +16 -0
  316. package/dist/node_modules/@boombot/core/workflow/dag.js +109 -0
  317. package/dist/node_modules/@boombot/core/workflow/engine.d.ts +34 -0
  318. package/dist/node_modules/@boombot/core/workflow/engine.js +304 -0
  319. package/dist/node_modules/@boombot/core/workflow/index.d.ts +3 -0
  320. package/dist/node_modules/@boombot/core/workflow/index.js +3 -0
  321. package/dist/node_modules/@boombot/core/workflow/types.d.ts +98 -0
  322. package/dist/node_modules/@boombot/core/workflow/types.js +21 -0
  323. package/dist/node_modules/@boombot/cronjobs/handlers.d.ts +11 -0
  324. package/dist/node_modules/@boombot/cronjobs/handlers.js +174 -0
  325. package/dist/node_modules/@boombot/cronjobs/index.d.ts +2 -0
  326. package/dist/node_modules/@boombot/cronjobs/index.js +2 -0
  327. package/dist/node_modules/@boombot/cronjobs/package.json +9 -0
  328. package/dist/node_modules/@boombot/cronjobs/service.d.ts +53 -0
  329. package/dist/node_modules/@boombot/cronjobs/service.js +200 -0
  330. package/dist/node_modules/@boombot/plugins/index.d.ts +2 -0
  331. package/dist/node_modules/@boombot/plugins/index.js +2 -0
  332. package/dist/node_modules/@boombot/plugins/installer.d.ts +45 -0
  333. package/dist/node_modules/@boombot/plugins/installer.js +487 -0
  334. package/dist/node_modules/@boombot/plugins/manager.d.ts +23 -0
  335. package/dist/node_modules/@boombot/plugins/manager.js +243 -0
  336. package/dist/node_modules/@boombot/plugins/package.json +9 -0
  337. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.d.ts +125 -0
  338. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.js +76 -0
  339. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.d.ts +220 -0
  340. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.js +60 -0
  341. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.d.ts +33 -0
  342. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.js +25 -0
  343. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.d.ts +4349 -0
  344. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.js +563 -0
  345. package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.d.ts +32 -0
  346. package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.js +61 -0
  347. package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.d.ts +13 -0
  348. package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.js +16 -0
  349. package/dist/node_modules/@boombot/protocol/gateway-protocol/events.d.ts +567 -0
  350. package/dist/node_modules/@boombot/protocol/gateway-protocol/events.js +395 -0
  351. package/dist/node_modules/@boombot/protocol/gateway-protocol/index.d.ts +20 -0
  352. package/dist/node_modules/@boombot/protocol/gateway-protocol/index.js +13 -0
  353. package/dist/node_modules/@boombot/protocol/gateway-protocol/types.d.ts +91 -0
  354. package/dist/node_modules/@boombot/protocol/gateway-protocol/types.js +7 -0
  355. package/dist/node_modules/@boombot/protocol/index.d.ts +4 -0
  356. package/dist/node_modules/@boombot/protocol/index.js +3 -0
  357. package/dist/node_modules/@boombot/protocol/package.json +9 -0
  358. package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.d.ts +41 -0
  359. package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.js +17 -0
  360. package/dist/node_modules/@boombot/protocol/plugin-sdk/index.d.ts +10 -0
  361. package/dist/node_modules/@boombot/protocol/plugin-sdk/index.js +10 -0
  362. package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.d.ts +58 -0
  363. package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.js +116 -0
  364. package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.d.ts +25 -0
  365. package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.js +1 -0
  366. package/dist/node_modules/@boombot/protocol/providers/cipher.d.ts +7 -0
  367. package/dist/node_modules/@boombot/protocol/providers/cipher.js +52 -0
  368. package/dist/node_modules/@boombot/protocol/providers/index.d.ts +19 -0
  369. package/dist/node_modules/@boombot/protocol/providers/index.js +19 -0
  370. package/dist/node_modules/@boombot/protocol/providers/key-roulette.d.ts +79 -0
  371. package/dist/node_modules/@boombot/protocol/providers/key-roulette.js +81 -0
  372. package/dist/node_modules/@boombot/protocol/providers/probe.d.ts +29 -0
  373. package/dist/node_modules/@boombot/protocol/providers/probe.js +96 -0
  374. package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.d.ts +11 -0
  375. package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.js +11 -0
  376. package/dist/node_modules/@boombot/protocol/providers/profiles/custom.d.ts +22 -0
  377. package/dist/node_modules/@boombot/protocol/providers/profiles/custom.js +222 -0
  378. package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.d.ts +7 -0
  379. package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.js +9 -0
  380. package/dist/node_modules/@boombot/protocol/providers/profiles/google.d.ts +10 -0
  381. package/dist/node_modules/@boombot/protocol/providers/profiles/google.js +10 -0
  382. package/dist/node_modules/@boombot/protocol/providers/profiles/index.d.ts +31 -0
  383. package/dist/node_modules/@boombot/protocol/providers/profiles/index.js +56 -0
  384. package/dist/node_modules/@boombot/protocol/providers/profiles/local.d.ts +10 -0
  385. package/dist/node_modules/@boombot/protocol/providers/profiles/local.js +11 -0
  386. package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.d.ts +7 -0
  387. package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.js +9 -0
  388. package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.d.ts +10 -0
  389. package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.js +10 -0
  390. package/dist/node_modules/@boombot/protocol/providers/profiles/openai.d.ts +7 -0
  391. package/dist/node_modules/@boombot/protocol/providers/profiles/openai.js +11 -0
  392. package/dist/node_modules/@boombot/protocol/providers/profiles/types.d.ts +58 -0
  393. package/dist/node_modules/@boombot/protocol/providers/profiles/types.js +1 -0
  394. package/dist/node_modules/@boombot/protocol/providers/profiles/xai.d.ts +7 -0
  395. package/dist/node_modules/@boombot/protocol/providers/profiles/xai.js +10 -0
  396. package/dist/node_modules/@boombot/protocol/providers/request-profile.d.ts +102 -0
  397. package/dist/node_modules/@boombot/protocol/providers/request-profile.js +118 -0
  398. package/dist/node_modules/@boombot/protocol/providers/service.d.ts +2 -0
  399. package/dist/node_modules/@boombot/protocol/providers/service.js +418 -0
  400. package/dist/node_modules/@boombot/protocol/providers/types.d.ts +141 -0
  401. package/dist/node_modules/@boombot/protocol/providers/types.js +16 -0
  402. package/dist/node_modules/@boombot/sandbox/fs-path.d.ts +13 -0
  403. package/dist/node_modules/@boombot/sandbox/fs-path.js +79 -0
  404. package/dist/node_modules/@boombot/sandbox/index.d.ts +13 -0
  405. package/dist/node_modules/@boombot/sandbox/index.js +13 -0
  406. package/dist/node_modules/@boombot/sandbox/native.d.ts +39 -0
  407. package/dist/node_modules/@boombot/sandbox/native.js +224 -0
  408. package/dist/node_modules/@boombot/sandbox/package.json +9 -0
  409. package/dist/node_modules/@boombot/sandbox/sandbox.d.ts +92 -0
  410. package/dist/node_modules/@boombot/sandbox/sandbox.js +229 -0
  411. package/dist/node_modules/@boombot/security/harness-guard/boundary.d.ts +22 -0
  412. package/dist/node_modules/@boombot/security/harness-guard/boundary.js +105 -0
  413. package/dist/node_modules/@boombot/security/harness-guard/gates.d.ts +90 -0
  414. package/dist/node_modules/@boombot/security/harness-guard/gates.js +791 -0
  415. package/dist/node_modules/@boombot/security/harness-guard/index.d.ts +23 -0
  416. package/dist/node_modules/@boombot/security/harness-guard/index.js +23 -0
  417. package/dist/node_modules/@boombot/security/harness-guard/policy.d.ts +20 -0
  418. package/dist/node_modules/@boombot/security/harness-guard/policy.js +70 -0
  419. package/dist/node_modules/@boombot/security/harness-guard/sanitizer.d.ts +53 -0
  420. package/dist/node_modules/@boombot/security/harness-guard/sanitizer.js +145 -0
  421. package/dist/node_modules/@boombot/security/harness-guard/types.d.ts +71 -0
  422. package/dist/node_modules/@boombot/security/harness-guard/types.js +10 -0
  423. package/dist/node_modules/@boombot/security/harness-guard/verifier.d.ts +59 -0
  424. package/dist/node_modules/@boombot/security/harness-guard/verifier.js +169 -0
  425. package/dist/node_modules/@boombot/security/index.d.ts +5 -0
  426. package/dist/node_modules/@boombot/security/index.js +9 -0
  427. package/dist/node_modules/@boombot/security/package.json +9 -0
  428. package/dist/node_modules/@boombot/security/policy/approval.d.ts +117 -0
  429. package/dist/node_modules/@boombot/security/policy/approval.js +223 -0
  430. package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.d.ts +10 -0
  431. package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.js +124 -0
  432. package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.d.ts +25 -0
  433. package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.js +70 -0
  434. package/dist/node_modules/@boombot/security/reasoning-guard/gate.d.ts +38 -0
  435. package/dist/node_modules/@boombot/security/reasoning-guard/gate.js +61 -0
  436. package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.d.ts +12 -0
  437. package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.js +234 -0
  438. package/dist/node_modules/@boombot/security/reasoning-guard/index.d.ts +17 -0
  439. package/dist/node_modules/@boombot/security/reasoning-guard/index.js +13 -0
  440. package/dist/node_modules/@boombot/security/reasoning-guard/policy.d.ts +15 -0
  441. package/dist/node_modules/@boombot/security/reasoning-guard/policy.js +39 -0
  442. package/dist/node_modules/@boombot/security/reasoning-guard/types.d.ts +46 -0
  443. package/dist/node_modules/@boombot/security/reasoning-guard/types.js +7 -0
  444. package/dist/node_modules/@boombot/security/security/approval.d.ts +63 -0
  445. package/dist/node_modules/@boombot/security/security/approval.js +140 -0
  446. package/dist/node_modules/@boombot/security/security/audit.d.ts +39 -0
  447. package/dist/node_modules/@boombot/security/security/audit.js +70 -0
  448. package/dist/node_modules/@boombot/security/security/index.d.ts +12 -0
  449. package/dist/node_modules/@boombot/security/security/index.js +12 -0
  450. package/dist/node_modules/@boombot/security/security/trust.d.ts +79 -0
  451. package/dist/node_modules/@boombot/security/security/trust.js +87 -0
  452. package/dist/package.json +5 -0
  453. package/dist/proto/agent_core.proto +56 -0
  454. package/dist/python/agent-core-python/pyproject.toml +40 -0
  455. package/dist/python/agent-core-python/src/boombot_agent/__init__.py +5 -0
  456. package/dist/python/agent-core-python/src/boombot_agent/generated/__init__.py +0 -0
  457. package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2.py +54 -0
  458. package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2_grpc.py +140 -0
  459. package/dist/python/agent-core-python/src/boombot_agent/rpc.py +265 -0
  460. package/dist/python/agent-core-python/src/boombot_agent/turn.py +577 -0
  461. package/dist/python/agent-core-python/src/boombot_ml/__init__.py +12 -0
  462. package/dist/python/agent-core-python/src/boombot_ml/embeddings.py +58 -0
  463. package/dist/python/agent-core-python/src/boombot_ml/training.py +156 -0
  464. package/dist/python/agent-core-python/uv.lock +2856 -0
  465. package/dist/web/assets/ChatView-BZrSD-64.js +262 -0
  466. package/dist/web/assets/ChatView-Cahbjez6.css +1 -0
  467. package/dist/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  468. package/dist/web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  469. package/dist/web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  470. package/dist/web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  471. package/dist/web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  472. package/dist/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  473. package/dist/web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  474. package/dist/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  475. package/dist/web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  476. package/dist/web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  477. package/dist/web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  478. package/dist/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  479. package/dist/web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  480. package/dist/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  481. package/dist/web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  482. package/dist/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  483. package/dist/web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  484. package/dist/web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  485. package/dist/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  486. package/dist/web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  487. package/dist/web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  488. package/dist/web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  489. package/dist/web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  490. package/dist/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  491. package/dist/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  492. package/dist/web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  493. package/dist/web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  494. package/dist/web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  495. package/dist/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  496. package/dist/web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  497. package/dist/web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  498. package/dist/web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  499. package/dist/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  500. package/dist/web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  501. package/dist/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  502. package/dist/web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  503. package/dist/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  504. package/dist/web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  505. package/dist/web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  506. package/dist/web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  507. package/dist/web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  508. package/dist/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  509. package/dist/web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  510. package/dist/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  511. package/dist/web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  512. package/dist/web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  513. package/dist/web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  514. package/dist/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  515. package/dist/web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  516. package/dist/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  517. package/dist/web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  518. package/dist/web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  519. package/dist/web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  520. package/dist/web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  521. package/dist/web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  522. package/dist/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  523. package/dist/web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  524. package/dist/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  525. package/dist/web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  526. package/dist/web/assets/MemoryView-BJbXqqs7.css +1 -0
  527. package/dist/web/assets/MemoryView-BfMq_6CD.js +1 -0
  528. package/dist/web/assets/SchedulesView-B22QmPR-.js +1 -0
  529. package/dist/web/assets/SchedulesView-C6XK7A8a.css +1 -0
  530. package/dist/web/assets/SessionsView-C1dqdhxI.css +1 -0
  531. package/dist/web/assets/SessionsView-DS0-aH2a.js +1 -0
  532. package/dist/web/assets/TasksView-Dtasg4hd.css +1 -0
  533. package/dist/web/assets/TasksView-ey0FLsW8.js +2 -0
  534. package/dist/web/assets/Textarea-DN3Zybl1.js +1 -0
  535. package/dist/web/assets/Tooltip-Bn2cqFPz.css +1 -0
  536. package/dist/web/assets/Tooltip-MzV2Gqnc.js +1 -0
  537. package/dist/web/assets/browser-Bnt73-Ub.js +8 -0
  538. package/dist/web/assets/index-BL8bi7Yt.css +1 -0
  539. package/dist/web/assets/index-CuPR73Tn.js +73 -0
  540. package/dist/web/favicon.svg +4 -0
  541. package/dist/web/index.html +26 -0
  542. package/dist/web/logo.jpg +0 -0
  543. package/dist/web/logo.png +0 -0
  544. package/package.json +51 -4
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Persistent Memory Manager (Hermes-style).
3
+ *
4
+ * Reads durable knowledge files (`MEMORY.md` and `USER.md`) from `~/.boombot/data/memory/`
5
+ * and formats them for injection into the turn's System Prompt.
6
+ *
7
+ * Mirrors Hermes Agent architecture:
8
+ * - `MEMORY.md`: System facts, conventions, tool quirks, and environment notes.
9
+ * - `USER.md`: User profile, identity, tone rules, and personal preferences.
10
+ */
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ export const MEMORY_BUDGET_CHARS = 2_200;
14
+ export const USER_BUDGET_CHARS = 1_375;
15
+ export class PersistentMemoryManager {
16
+ memoryDir;
17
+ memoryPath;
18
+ userPath;
19
+ constructor(dataDir) {
20
+ this.memoryDir = join(dataDir, 'memory');
21
+ this.memoryPath = join(this.memoryDir, 'MEMORY.md');
22
+ this.userPath = join(this.memoryDir, 'USER.md');
23
+ this.ensureInitialized();
24
+ }
25
+ ensureInitialized() {
26
+ if (!existsSync(this.memoryDir)) {
27
+ mkdirSync(this.memoryDir, { recursive: true });
28
+ }
29
+ }
30
+ getFilePath(target) {
31
+ return target === 'user' ? this.userPath : this.memoryPath;
32
+ }
33
+ getBudget(target) {
34
+ return target === 'user' ? USER_BUDGET_CHARS : MEMORY_BUDGET_CHARS;
35
+ }
36
+ readRaw(target) {
37
+ const file = this.getFilePath(target);
38
+ if (!existsSync(file))
39
+ return '';
40
+ try {
41
+ return readFileSync(file, 'utf8').trim();
42
+ }
43
+ catch {
44
+ return '';
45
+ }
46
+ }
47
+ writeRaw(target, content) {
48
+ this.ensureInitialized();
49
+ const file = this.getFilePath(target);
50
+ writeFileSync(file, content.trim(), 'utf8');
51
+ }
52
+ getAtoms(target) {
53
+ const raw = this.readRaw(target);
54
+ if (!raw)
55
+ return [];
56
+ return raw
57
+ .split(/\n§\n|\n§\r\n|\r\n§\r\n/)
58
+ .map((a) => a.trim())
59
+ .filter(Boolean);
60
+ }
61
+ setAtoms(target, atoms) {
62
+ const maxChars = this.getBudget(target);
63
+ const combined = atoms.filter(Boolean).join('\n§\n');
64
+ const currentChars = combined.length;
65
+ if (currentChars > maxChars) {
66
+ return {
67
+ success: false,
68
+ target,
69
+ currentChars,
70
+ maxChars,
71
+ percentUsed: Math.round((currentChars / maxChars) * 100),
72
+ message: `Memory update rejected: exceeds character budget (${currentChars}/${maxChars} chars). Remove or consolidate entries first.`,
73
+ };
74
+ }
75
+ this.writeRaw(target, combined);
76
+ return {
77
+ success: true,
78
+ target,
79
+ currentChars,
80
+ maxChars,
81
+ percentUsed: Math.round((currentChars / maxChars) * 100),
82
+ message: `Memory updated successfully (${currentChars}/${maxChars} chars, ${Math.round((currentChars / maxChars) * 100)}%).`,
83
+ };
84
+ }
85
+ applyOperation(op, defaultTarget = 'memory') {
86
+ const target = op.target ?? defaultTarget;
87
+ let atoms = this.getAtoms(target);
88
+ switch (op.action) {
89
+ case 'add': {
90
+ const text = (op.content ?? op.new_text ?? '').trim();
91
+ if (!text) {
92
+ throw new Error("Action 'add' requires non-empty 'content'.");
93
+ }
94
+ atoms.push(text);
95
+ return this.setAtoms(target, atoms);
96
+ }
97
+ case 'replace': {
98
+ const needle = (op.old_text ?? '').trim();
99
+ const replacement = (op.content ?? op.new_text ?? '').trim();
100
+ if (!needle) {
101
+ throw new Error("Action 'replace' requires 'old_text' to identify existing entry.");
102
+ }
103
+ if (!replacement) {
104
+ throw new Error("Action 'replace' requires 'content' or 'new_text'.");
105
+ }
106
+ const index = atoms.findIndex((a) => a.includes(needle));
107
+ if (index === -1) {
108
+ return {
109
+ success: false,
110
+ target,
111
+ currentChars: this.readRaw(target).length,
112
+ maxChars: this.getBudget(target),
113
+ percentUsed: Math.round((this.readRaw(target).length / this.getBudget(target)) * 100),
114
+ message: `Entry matching '${needle}' not found in ${target}.`,
115
+ };
116
+ }
117
+ atoms[index] = replacement;
118
+ return this.setAtoms(target, atoms);
119
+ }
120
+ case 'remove': {
121
+ const needle = (op.old_text ?? '').trim();
122
+ if (!needle) {
123
+ throw new Error("Action 'remove' requires 'old_text'.");
124
+ }
125
+ const originalLen = atoms.length;
126
+ atoms = atoms.filter((a) => !a.includes(needle));
127
+ if (atoms.length === originalLen) {
128
+ return {
129
+ success: false,
130
+ target,
131
+ currentChars: this.readRaw(target).length,
132
+ maxChars: this.getBudget(target),
133
+ percentUsed: Math.round((this.readRaw(target).length / this.getBudget(target)) * 100),
134
+ message: `Entry matching '${needle}' not found in ${target}.`,
135
+ };
136
+ }
137
+ return this.setAtoms(target, atoms);
138
+ }
139
+ default:
140
+ throw new Error(`Unsupported memory action: ${String(op.action)}`);
141
+ }
142
+ }
143
+ applyBatch(target, operations) {
144
+ let atoms = this.getAtoms(target);
145
+ for (const op of operations) {
146
+ switch (op.action) {
147
+ case 'add': {
148
+ const text = (op.content ?? op.new_text ?? '').trim();
149
+ if (text)
150
+ atoms.push(text);
151
+ break;
152
+ }
153
+ case 'replace': {
154
+ const needle = (op.old_text ?? '').trim();
155
+ const rep = (op.content ?? op.new_text ?? '').trim();
156
+ if (needle && rep) {
157
+ const idx = atoms.findIndex((a) => a.includes(needle));
158
+ if (idx !== -1)
159
+ atoms[idx] = rep;
160
+ }
161
+ break;
162
+ }
163
+ case 'remove': {
164
+ const needle = (op.old_text ?? '').trim();
165
+ if (needle) {
166
+ atoms = atoms.filter((a) => !a.includes(needle));
167
+ }
168
+ break;
169
+ }
170
+ }
171
+ }
172
+ return this.setAtoms(target, atoms);
173
+ }
174
+ formatForSystemPrompt() {
175
+ const memoryRaw = this.readRaw('memory');
176
+ const userRaw = this.readRaw('user');
177
+ const sections = [];
178
+ if (memoryRaw) {
179
+ const len = memoryRaw.length;
180
+ const pct = Math.round((len / MEMORY_BUDGET_CHARS) * 100);
181
+ sections.push('══════════════════════════════════════════════\n' +
182
+ `MEMORY (your personal notes) [${pct}% — ${len.toLocaleString()}/${MEMORY_BUDGET_CHARS.toLocaleString()} chars]\n` +
183
+ '══════════════════════════════════════════════\n' +
184
+ memoryRaw);
185
+ }
186
+ if (userRaw) {
187
+ const len = userRaw.length;
188
+ const pct = Math.round((len / USER_BUDGET_CHARS) * 100);
189
+ sections.push('══════════════════════════════════════════════\n' +
190
+ `USER PROFILE (who the user is) [${pct}% — ${len.toLocaleString()}/${USER_BUDGET_CHARS.toLocaleString()} chars]\n` +
191
+ '══════════════════════════════════════════════\n' +
192
+ userRaw);
193
+ }
194
+ return sections.join('\n\n');
195
+ }
196
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Gateway boot wiring for `@boombot/protocol`.
3
+ *
4
+ * Reads the master key from `BOOMBOT_MASTER_KEY` (boot fails loudly when it is
5
+ * missing, with instructions to generate one) and attaches a ready
6
+ * `ProviderService` to `ctx.providerService`. The gateway's command handlers
7
+ * (`handlers/providers.ts`) and the agent turn wiring consume it from there.
8
+ */
9
+ import { join } from "node:path";
10
+ import { createProviderService } from "@boombot/protocol";
11
+ import { resolveEmbeddingClient, resolveLlmClient } from "./llm-client.js";
12
+ /**
13
+ * Boot the provider service. Returns a shutdown function (file-backed store:
14
+ * nothing to close, kept for a uniform service lifecycle).
15
+ */
16
+ export async function startProvidersService(ctx) {
17
+ const masterKey = process.env["BOOMBOT_MASTER_KEY"];
18
+ if (!masterKey) {
19
+ throw new Error("[boombot-gateway] BOOMBOT_MASTER_KEY is not set — provider API keys are " +
20
+ "stored encrypted at rest and require a master key to boot.\n" +
21
+ "Generate one with:\n" +
22
+ ' node -e "console.log(require(\'node:crypto\').randomBytes(32).toString(\'hex\'))"\n' +
23
+ "Then start the gateway with:\n" +
24
+ " BOOMBOT_MASTER_KEY=<hex> pnpm --filter @boombot/gateway start");
25
+ }
26
+ const service = createProviderService({
27
+ storagePath: join(ctx.dataDir, "providers.json"),
28
+ masterKey,
29
+ });
30
+ await service.load();
31
+ // Attach the real LLM resolver: the turn loop's `LazyLlmClient` calls
32
+ // `resolveLlm()` through the structural `ProviderServiceLike` contract
33
+ // (turns/runtime-deps.ts). It stays off the `@boombot/protocol`
34
+ // interface on purpose — that package is a leaf and must not import
35
+ // `@boombot/core` for the `LlmClient` type.
36
+ ctx.providerService = {
37
+ ...service,
38
+ resolveLlm: () => resolveLlmClient(service),
39
+ resolveEmbeddings: () => resolveEmbeddingClient(service),
40
+ };
41
+ return async () => {
42
+ // File-backed store: no connections to close.
43
+ };
44
+ }
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Gateway boot wiring for `@boombot/core`.
3
+ *
4
+ * Starts the background task runner: a file-backed store at
5
+ * `<dataDir>/tasks.json`, a `TurnRunner` adapter over the real turn service
6
+ * (one turn per task step), and a `TaskEvent` -> `StreamEvent` bridge onto
7
+ * the gateway event bus. Attaches the ready `TaskRunner` to
8
+ * `ctx.taskService` for the `task.*` command handlers.
9
+ *
10
+ * Requires the turn service: without it the starter throws and `services.ts`
11
+ * boots degraded (`task.*` commands report unavailable).
12
+ */
13
+ import { join } from 'node:path';
14
+ import { createTaskRunner, createTaskStore, } from '@boombot/core';
15
+ import { subscribeEvent, subscribeTurnDone } from '../events.js';
16
+ /**
17
+ * Boot the task runner service. `recover()` reaps tasks left
18
+ * running/paused/awaiting-approval by a previous process as `interrupted`.
19
+ * Returns a shutdown function that cancels every in-flight task (running or
20
+ * awaiting approval) so step turns do not outlive the gateway.
21
+ */
22
+ export async function startTasksService(ctx) {
23
+ const turnService = ctx.turnService;
24
+ if (turnService === undefined) {
25
+ // services.ts catches this and boots degraded (task.* unavailable).
26
+ throw new Error('turn service is not running: cannot start the task runner');
27
+ }
28
+ const store = createTaskStore({ storagePath: join(ctx.dataDir, 'tasks.json') });
29
+ await store.load();
30
+ const runner = createTaskRunner({
31
+ store,
32
+ turnRunner: adaptTurnService(turnService),
33
+ onEvent: (event) => {
34
+ ctx.events.publish(toStreamEvent(event));
35
+ },
36
+ });
37
+ await runner.recover();
38
+ ctx.taskService = runner;
39
+ const tasks = await runner.list();
40
+ const interrupted = tasks.filter((task) => task.status === 'interrupted').length;
41
+ ctx.log('info', 'task runner ready', { tasks: tasks.length, interrupted });
42
+ return async () => {
43
+ const current = await runner.list();
44
+ const inFlight = current.filter((task) => task.status === 'running' || task.status === 'awaiting_approval');
45
+ await Promise.all(inFlight.map(async (task) => {
46
+ try {
47
+ await runner.cancel(task.id);
48
+ }
49
+ catch (error) {
50
+ ctx.log('warn', `failed to cancel in-flight task on shutdown: ${task.id}`, {
51
+ error: error instanceof Error ? error.message : String(error),
52
+ });
53
+ }
54
+ }));
55
+ };
56
+ }
57
+ /**
58
+ * Adapt the gateway turn service to the task runner's `TurnRunner` port.
59
+ * Each step submits a turn in the task's shared session and waits for its
60
+ * terminal stream event.
61
+ */
62
+ function adaptTurnService(turnService) {
63
+ return {
64
+ runTurn: (input) => runStepTurn(turnService, input),
65
+ approveTurn: async (runId, approved, editedArgs) => {
66
+ const result = await turnService.approveTurn?.(runId, approved, editedArgs);
67
+ return result?.resumed ?? false;
68
+ },
69
+ };
70
+ }
71
+ async function runStepTurn(turnService, input) {
72
+ const { turnId, sessionId } = await turnService.submit({
73
+ input: input.prompt,
74
+ ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
75
+ });
76
+ if (input.signal.aborted) {
77
+ await turnService.cancel(turnId).catch(() => false);
78
+ throw new Error('turn aborted');
79
+ }
80
+ return new Promise((resolve, reject) => {
81
+ const cleanup = () => {
82
+ unsubscribeDone();
83
+ unsubscribeError();
84
+ unsubscribeApproval();
85
+ input.signal.removeEventListener('abort', onAbort);
86
+ };
87
+ const settle = (result) => {
88
+ cleanup();
89
+ resolve(result);
90
+ };
91
+ const onTurnDone = (payload) => {
92
+ if (payload.turnId !== turnId)
93
+ return;
94
+ if (payload.status === 'completed') {
95
+ settle({
96
+ status: 'completed',
97
+ sessionId,
98
+ ...(payload.output !== undefined ? { output: payload.output } : {}),
99
+ });
100
+ }
101
+ else {
102
+ // A non-completed terminal status ('cancelled', ...) is a failed step.
103
+ settle({ status: 'failed', sessionId, error: `turn ${payload.status}` });
104
+ }
105
+ };
106
+ const onTurnError = (event) => {
107
+ const payload = readTurnErrorPayload(event);
108
+ if (payload === undefined || payload.turnId !== turnId)
109
+ return;
110
+ settle({ status: 'failed', sessionId, error: payload.error });
111
+ };
112
+ const onAbort = () => {
113
+ // Best effort: the turn may already be gone. Either way the step
114
+ // reports the abort; a racing terminal event is ignored because
115
+ // cleanup() unsubscribed us first.
116
+ void (async () => {
117
+ try {
118
+ await turnService.cancel(turnId);
119
+ }
120
+ catch {
121
+ // The turn is gone or already settled; still report the abort.
122
+ }
123
+ cleanup();
124
+ reject(new Error('turn aborted'));
125
+ })();
126
+ };
127
+ const unsubscribeDone = subscribeTurnDone(onTurnDone);
128
+ const unsubscribeError = subscribeEvent('agent.turn.error', onTurnError);
129
+ const unsubscribeApproval = subscribeEvent('turn.approval_required', (event) => {
130
+ const payload = readApprovalPayload(event);
131
+ if (payload === undefined || payload.turnId !== turnId)
132
+ return;
133
+ input.onEvent?.({
134
+ type: 'approval_required',
135
+ runId: payload.runId,
136
+ toolName: payload.toolName,
137
+ args: payload.args,
138
+ reason: payload.reason,
139
+ });
140
+ });
141
+ input.signal.addEventListener('abort', onAbort, { once: true });
142
+ // Replay a retained terminal event: a fail-fast turn can settle between
143
+ // submit() resolving and the subscriptions above attaching. The turn
144
+ // service retains terminal events for exactly this late-subscriber case
145
+ // (see `handleTurnSSE` in events.ts).
146
+ const replay = turnService.getTerminalEvent?.(turnId);
147
+ if (replay !== undefined) {
148
+ const donePayload = readTurnDonePayload(replay);
149
+ if (donePayload !== undefined) {
150
+ onTurnDone(donePayload);
151
+ }
152
+ else {
153
+ onTurnError(replay);
154
+ }
155
+ }
156
+ });
157
+ }
158
+ /** Read `{ turnId, status, output? }` from an `agent.turn.done` stream event. */
159
+ function readTurnDonePayload(event) {
160
+ if (event.type !== 'agent.turn.done')
161
+ return undefined;
162
+ const payload = event.payload;
163
+ if (typeof payload !== 'object' || payload === null)
164
+ return undefined;
165
+ const record = payload;
166
+ const { turnId, status, output } = record;
167
+ if (typeof turnId !== 'string' || typeof status !== 'string')
168
+ return undefined;
169
+ if (output !== undefined && typeof output !== 'string')
170
+ return undefined;
171
+ return { turnId, status, output };
172
+ }
173
+ /** Read `{ turnId, error }` from an `agent.turn.error` stream event. */
174
+ function readTurnErrorPayload(event) {
175
+ const payload = event.payload;
176
+ if (typeof payload !== 'object' || payload === null)
177
+ return undefined;
178
+ const { turnId, error } = payload;
179
+ if (typeof turnId !== 'string' || typeof error !== 'string')
180
+ return undefined;
181
+ return { turnId, error };
182
+ }
183
+ /** Read the `turn.approval_required` payload (turnId + run correlation). */
184
+ function readApprovalPayload(event) {
185
+ const payload = event.payload;
186
+ if (typeof payload !== 'object' || payload === null)
187
+ return undefined;
188
+ const record = payload;
189
+ const { turnId, runId, toolName, args, reason } = record;
190
+ if (typeof turnId !== 'string' ||
191
+ typeof runId !== 'string' ||
192
+ typeof toolName !== 'string' ||
193
+ typeof reason !== 'string' ||
194
+ typeof args !== 'object' ||
195
+ args === null) {
196
+ return undefined;
197
+ }
198
+ return { turnId, runId, toolName, args: args, reason };
199
+ }
200
+ // ---------------------------------------------------------------------------
201
+ // TaskEvent -> StreamEvent bridge.
202
+ // ---------------------------------------------------------------------------
203
+ /**
204
+ * Map a task-runner `TaskEvent` onto the wire `task.*` stream event shape.
205
+ * Built directly (no `parseEvent`): the payload mirrors the `TaskEvent`
206
+ * fields 1:1 so it validates against the `task.*` schemas once they land
207
+ * in `@boombot/protocol`.
208
+ */
209
+ function toStreamEvent(event) {
210
+ switch (event.type) {
211
+ case 'task.progress':
212
+ return streamEvent(event.type, {
213
+ taskId: event.taskId,
214
+ stepIndex: event.stepIndex,
215
+ totalSteps: event.totalSteps,
216
+ ...(event.detail !== undefined ? { detail: event.detail } : {}),
217
+ });
218
+ case 'task.checkpoint':
219
+ return streamEvent(event.type, { taskId: event.taskId, stepIndex: event.stepIndex });
220
+ case 'task.awaiting_approval':
221
+ return streamEvent(event.type, {
222
+ taskId: event.taskId,
223
+ runId: event.runId,
224
+ toolName: event.toolName,
225
+ reason: event.reason,
226
+ });
227
+ case 'task.failed':
228
+ return streamEvent(event.type, { taskId: event.taskId, error: event.error });
229
+ default:
230
+ return streamEvent(event.type, { taskId: event.taskId });
231
+ }
232
+ }
233
+ function streamEvent(type, payload) {
234
+ // The `task.*` schemas are additive to the protocol union; cast across the
235
+ // currently closed union so this compiles on both sides of that change.
236
+ return { type, payload };
237
+ }
@@ -0,0 +1,124 @@
1
+ import { DEFAULT_GUARD_CONFIG, EvidenceLedger, verifyTurnWithClaims, } from '@boombot/security';
2
+ /** A per-turn verification middleware for the agent-core turn pipeline. */
3
+ export function createVerificationMiddleware(deps) {
4
+ const config = { ...DEFAULT_GUARD_CONFIG, ...deps.config };
5
+ const ledger = new EvidenceLedger(config.maxExcerptChars);
6
+ // callId -> the model's original arguments for that call, captured from
7
+ // the `modelRound` phase so `toolRound` evidence keeps the args the
8
+ // model actually sent (the phase result only carries the call id).
9
+ const callArgs = new Map();
10
+ return {
11
+ name: 'reasoning-guard',
12
+ afterPhase(phase, _ctx, result) {
13
+ if (phase === 'modelRound') {
14
+ const round = result;
15
+ for (const call of round?.toolCalls ?? []) {
16
+ callArgs.set(call.id, call.arguments);
17
+ }
18
+ return;
19
+ }
20
+ if (phase === 'toolRound') {
21
+ const outcome = result;
22
+ for (const toolResult of outcome?.results ?? []) {
23
+ // Only executed calls become evidence. Policy denials and
24
+ // approver rejections never reach a handler, so they are skipped.
25
+ if (toolResult.deniedByPolicy === true ||
26
+ toolResult.rejectedByApprover === true) {
27
+ continue;
28
+ }
29
+ ledger.record({
30
+ tool: toolResult.name,
31
+ args: callArgs.get(toolResult.callId) ?? {
32
+ callId: toolResult.callId,
33
+ },
34
+ output: toolResult.output,
35
+ error: toolResult.error,
36
+ });
37
+ }
38
+ }
39
+ },
40
+ wrapPhase(phase, next) {
41
+ if (phase !== 'finalize') {
42
+ return next();
43
+ }
44
+ return (async () => {
45
+ const result = (await next());
46
+ if (config.mode === 'off') {
47
+ return result;
48
+ }
49
+ let verified;
50
+ let draft;
51
+ try {
52
+ draft = lastAssistantText(result.messages);
53
+ verified = verifyTurnWithClaims(draft, ledger, config);
54
+ }
55
+ catch {
56
+ // Verification must never break a turn: fall back to the
57
+ // unmodified finalizer result.
58
+ return result;
59
+ }
60
+ try {
61
+ deps.onVerified?.(verified);
62
+ }
63
+ catch {
64
+ // A broken listener must never break the turn.
65
+ }
66
+ try {
67
+ deps.publish(buildVerificationEvent(deps, verified));
68
+ }
69
+ catch {
70
+ // A broken SSE stream must never break the turn.
71
+ }
72
+ if (verified.text === draft) {
73
+ return result;
74
+ }
75
+ // Strict mode rewrote ungrounded spans: persist the verified text.
76
+ return {
77
+ ...result,
78
+ messages: replaceLastAssistantText(result.messages, verified.text),
79
+ };
80
+ })();
81
+ },
82
+ };
83
+ }
84
+ /** Build the schema-valid `turn.verification` stream event. */
85
+ function buildVerificationEvent(deps, verified) {
86
+ const claimById = new Map();
87
+ for (const claim of verified.claims) {
88
+ claimById.set(claim.id, claim.text);
89
+ }
90
+ const payload = {
91
+ turnId: deps.turnId,
92
+ runId: deps.runId,
93
+ report: {
94
+ verdicts: verified.report.verdicts.map((verdict) => {
95
+ const claim = claimById.get(verdict.claimId);
96
+ return claim === undefined
97
+ ? { verdict: verdict.verdict }
98
+ : { verdict: verdict.verdict, claim };
99
+ }),
100
+ ungroundedCount: verified.report.ungroundedCount,
101
+ },
102
+ };
103
+ return { type: 'turn.verification', payload };
104
+ }
105
+ /** Content of the last assistant message, or '' when there is none. */
106
+ function lastAssistantText(messages) {
107
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
108
+ const m = messages[i];
109
+ if (m !== undefined && m.role === 'assistant') {
110
+ return m.content;
111
+ }
112
+ }
113
+ return '';
114
+ }
115
+ /** Replace the content of the last assistant message, keeping other fields. */
116
+ function replaceLastAssistantText(messages, text) {
117
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
118
+ const m = messages[i];
119
+ if (m !== undefined && m.role === 'assistant') {
120
+ return [...messages.slice(0, i), { ...m, content: text }, ...messages.slice(i + 1)];
121
+ }
122
+ }
123
+ return [...messages];
124
+ }
@@ -0,0 +1,48 @@
1
+ const DATA_URL = /^data:(image\/(?:png|jpeg|gif|webp));base64,([A-Za-z0-9+/]+={0,2})$/i;
2
+ /** Validate image references; only remote HTTP(S) or supported base64 image data URLs are accepted. */
3
+ export function validateImageSource(source) {
4
+ if (/^https?:\/\//i.test(source))
5
+ return 'remote';
6
+ const match = DATA_URL.exec(source);
7
+ if (match) {
8
+ const data = match[2] ?? '';
9
+ if (data.length % 4 === 1)
10
+ throw new Error('Invalid image base64 payload.');
11
+ return 'data';
12
+ }
13
+ if (source.startsWith('data:'))
14
+ throw new Error('Image data URL must use a supported image media type and base64 encoding.');
15
+ throw new Error('Image source must use https://, http://, or a supported data:image/*;base64 URL.');
16
+ }
17
+ export function toOpenAiVisionContent(text, images) {
18
+ const content = [{ type: 'text', text }];
19
+ for (const image of images) {
20
+ validateImageSource(image.url);
21
+ content.push({
22
+ type: 'image_url',
23
+ image_url: { url: image.url, detail: image.detail ?? 'auto' },
24
+ });
25
+ }
26
+ return content;
27
+ }
28
+ export function toAnthropicVisionContent(text, images) {
29
+ const content = [{ type: 'text', text }];
30
+ for (const image of images) {
31
+ const sourceType = validateImageSource(image.url);
32
+ if (sourceType === 'remote') {
33
+ content.push({
34
+ type: 'image',
35
+ source: { type: 'url', url: image.url },
36
+ });
37
+ continue;
38
+ }
39
+ const match = DATA_URL.exec(image.url);
40
+ if (!match)
41
+ throw new Error('Invalid image data URL.');
42
+ content.push({
43
+ type: 'image',
44
+ source: { type: 'base64', media_type: match[1], data: match[2] },
45
+ });
46
+ }
47
+ return content;
48
+ }