@theowlops/boombot 0.0.0-stage → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +244 -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,100 @@
1
+ /**
2
+ * Command handlers for `agent.turn.submit` / `agent.turn.cancel` /
3
+ * `turn.approve`.
4
+ *
5
+ * Registered on the coordinator-owned command registry; each handler
6
+ * receives the service context (which carries the started turn service),
7
+ * the validated command payload, and the request meta.
8
+ *
9
+ * Response shapes: the protocol response schemas require
10
+ * `{ turnId, status }`. The handlers return a superset —
11
+ * `{ turnId, sessionId, status }` for submit (so the client learns the
12
+ * created session id) and `{ turnId, ok, status }` for cancel —
13
+ * which stays schema-valid (zod strips unknown fields) while carrying
14
+ * the fields callers need.
15
+ */
16
+ import { ProtocolError } from '@boombot/protocol';
17
+ export function registerTurnHandlers(registry) {
18
+ registry.register('agent.turn.submit', async (ctx, payload) => {
19
+ const service = ctx.turnService;
20
+ if (service === undefined) {
21
+ throw new Error('turn service is not running: agent.turn.submit is unavailable');
22
+ }
23
+ const { sessionId, message } = readSubmitPayload(payload);
24
+ const result = await service.submit({ sessionId, input: message });
25
+ return { turnId: result.turnId, sessionId: result.sessionId, status: 'running' };
26
+ });
27
+ registry.register('agent.turn.cancel', async (ctx, payload) => {
28
+ const service = ctx.turnService;
29
+ if (service === undefined) {
30
+ throw new Error('turn service is not running: agent.turn.cancel is unavailable');
31
+ }
32
+ const { turnId } = readCancelPayload(payload);
33
+ const ok = await service.cancel(turnId);
34
+ const status = ok ? 'cancelled' : 'completed';
35
+ return { turnId, ok, status };
36
+ });
37
+ registry.register('turn.approve', async (ctx, payload) => {
38
+ const service = ctx.turnService;
39
+ if (service === undefined) {
40
+ throw new Error('turn service is not running: turn.approve is unavailable');
41
+ }
42
+ if (service.approveTurn === undefined) {
43
+ throw new Error('turn.approve is not supported by this turn service');
44
+ }
45
+ const { runId, approved, editedArgs } = readApprovePayload(payload);
46
+ const { found, resumed } = await service.approveTurn(runId, approved, editedArgs);
47
+ if (!found) {
48
+ // Client error (400 via the server's ProtocolError mapping), not a
49
+ // 500: the runId is well-formed, it is just not awaiting approval
50
+ // (timed out, already answered, or never existed).
51
+ throw new ProtocolError('INVALID_PAYLOAD', `no pending approval for runId: ${runId}`, { runId });
52
+ }
53
+ return { runId, approved, resumed };
54
+ });
55
+ }
56
+ function readSubmitPayload(payload) {
57
+ if (typeof payload !== 'object' || payload === null) {
58
+ throw new Error('agent.turn.submit: payload must be an object');
59
+ }
60
+ const record = payload;
61
+ const { sessionId, message } = record;
62
+ if (typeof message !== 'string' || message.trim() === '') {
63
+ throw new Error('agent.turn.submit: message must be a non-empty string');
64
+ }
65
+ if (sessionId !== undefined && typeof sessionId !== 'string') {
66
+ throw new Error('agent.turn.submit: sessionId must be a string when provided');
67
+ }
68
+ return sessionId === undefined ? { message } : { sessionId, message };
69
+ }
70
+ function readCancelPayload(payload) {
71
+ if (typeof payload !== 'object' || payload === null) {
72
+ throw new Error('agent.turn.cancel: payload must be an object');
73
+ }
74
+ const { turnId } = payload;
75
+ if (typeof turnId !== 'string' || turnId === '') {
76
+ throw new Error('agent.turn.cancel: turnId must be a non-empty string');
77
+ }
78
+ return { turnId };
79
+ }
80
+ function readApprovePayload(payload) {
81
+ if (typeof payload !== 'object' || payload === null) {
82
+ throw new Error('turn.approve: payload must be an object');
83
+ }
84
+ const record = payload;
85
+ const { runId, approved, editedArgs } = record;
86
+ if (typeof runId !== 'string' || runId === '') {
87
+ throw new Error('turn.approve: runId must be a non-empty string');
88
+ }
89
+ if (typeof approved !== 'boolean') {
90
+ throw new Error('turn.approve: approved must be a boolean');
91
+ }
92
+ if (editedArgs !== undefined && (typeof editedArgs !== 'object' || editedArgs === null)) {
93
+ throw new Error('turn.approve: editedArgs must be an object when provided');
94
+ }
95
+ return {
96
+ runId,
97
+ approved,
98
+ editedArgs: editedArgs,
99
+ };
100
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * BoomBot gateway entry point (coordinator-owned).
3
+ *
4
+ * `startGateway()` boots the full runtime: config → context (sessions,
5
+ * registry, event bus) → handlers → services → HTTP server. Exported for
6
+ * the `boombot gateway` CLI command (`apps/cli`), which dynamic-imports
7
+ * this module and calls `startGateway()`.
8
+ */
9
+ import { mkdirSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { describeResearchConfig, loadResearchConfig } from '@boombot/core';
12
+ import { loadConfig } from './config.js';
13
+ import { defaultEnvPath, loadEnvFile } from './env-file.js';
14
+ import { handleSSE, publishEvent } from './events.js';
15
+ import { registerAllHandlers } from './handlers/index.js';
16
+ import { HandlerRegistry } from './handlers/registry.js';
17
+ import { createGatewayServer } from './server.js';
18
+ import { startServices } from './services.js';
19
+ import { SqliteSessionStore } from './sessions.js';
20
+ import { isWebUiEnabled } from './static.js';
21
+ export { handleSSE, publishEvent };
22
+ /** Build the service context: config, durable sessions, registry, event bus. */
23
+ function createContext() {
24
+ /*
25
+ * Load `.env` BEFORE `loadConfig()`, and load it here rather than in `main.ts`:
26
+ * the real entry path is `boombot gateway`, i.e. the CLI dynamic-imports this
27
+ * module and calls `startGateway()` — `main.ts` is not involved. `createContext`
28
+ * is where every config value flows through, so it's also the one place that
29
+ * must be certain.
30
+ *
31
+ * Print the count of loaded values with the path, NEVER the values: this is
32
+ * the line that answers "was the token I just pasted into `.env` picked up"
33
+ * without leaking anything.
34
+ */
35
+ const envKeys = loadEnvFile();
36
+ const config = loadConfig();
37
+ if (envKeys > 0) {
38
+ console.log(`[gateway] [info] env: loaded ${envKeys} value(s) from ${defaultEnvPath()}`);
39
+ }
40
+ mkdirSync(config.dataDir, { recursive: true });
41
+ const sessions = SqliteSessionStore.open(join(config.dataDir, 'sessions.sqlite'));
42
+ const registry = new HandlerRegistry();
43
+ const ctx = {
44
+ config,
45
+ dataDir: config.dataDir,
46
+ log: (level, msg, meta) => {
47
+ const extra = meta !== undefined && Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : '';
48
+ console.log(`[gateway] [${level}] ${msg}${extra}`);
49
+ },
50
+ events: { publish: publishEvent },
51
+ sessions,
52
+ registry,
53
+ };
54
+ return ctx;
55
+ }
56
+ function createShutdown(stop, sessions) {
57
+ let stopping = false;
58
+ const shutdown = async () => {
59
+ if (stopping)
60
+ return;
61
+ stopping = true;
62
+ process.off('SIGINT', signalShutdown);
63
+ process.off('SIGTERM', signalShutdown);
64
+ console.log('[gateway] shutting down…');
65
+ try {
66
+ await stop();
67
+ }
68
+ finally {
69
+ sessions.close();
70
+ }
71
+ console.log('[gateway] stopped');
72
+ };
73
+ const signalShutdown = () => void shutdown().then(() => process.exit(0));
74
+ process.on('SIGINT', signalShutdown);
75
+ process.on('SIGTERM', signalShutdown);
76
+ return shutdown;
77
+ }
78
+ /**
79
+ * Boot the gateway and start listening. Resolves when the server is
80
+ * listening; the process keeps running until SIGINT/SIGTERM.
81
+ */
82
+ export async function startGatewayManaged() {
83
+ const ctx = createContext();
84
+ // Services first: some handlers capture services at registration time
85
+ // (providers), others read them per-call (turn/schedule/memory/channels).
86
+ const stopServices = await startServices(ctx);
87
+ registerAllHandlers(ctx, ctx.registry);
88
+ const server = createGatewayServer(ctx);
89
+ const stop = async () => {
90
+ await stopServices();
91
+ await new Promise((resolve) => server.close(() => resolve()));
92
+ };
93
+ try {
94
+ await new Promise((resolve, reject) => {
95
+ const onError = (error) => reject(error);
96
+ server.once('error', onError);
97
+ server.listen(ctx.config.port, ctx.config.host, () => {
98
+ server.off('error', onError);
99
+ resolve();
100
+ });
101
+ });
102
+ }
103
+ catch (error) {
104
+ await stopServices();
105
+ ctx.sessions.close();
106
+ throw error;
107
+ }
108
+ const shutdown = createShutdown(stop, ctx.sessions);
109
+ console.log(`[gateway] listening on http://${ctx.config.host}:${ctx.config.port} (wire v1)`);
110
+ // Provider summary reads from the same env source as the turn service (the
111
+ // gateway config has no `research` field yet) — list ids only, NEVER print keys.
112
+ const research = describeResearchConfig(loadResearchConfig());
113
+ console.log(`[gateway] research: search ${research.search.join(', ')} | extract ${research.extract}`);
114
+ if (isWebUiEnabled()) {
115
+ console.log(`[gateway] web UI: http://${ctx.config.host}:${ctx.config.port}/`);
116
+ }
117
+ else {
118
+ console.log('[gateway] web UI assets not found — API-only mode ' +
119
+ '(dev: run the web UI with `pnpm --filter @boombot/web dev`)');
120
+ }
121
+ return shutdown;
122
+ }
123
+ /** Boot for callers that only need the process kept alive. */
124
+ export async function startGateway() {
125
+ await startGatewayManaged();
126
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * BoomBot gateway — process entry point.
3
+ *
4
+ * Boots the full phase-2 runtime (HTTP server, command dispatch, SSE,
5
+ * scheduler, memory, channels).
6
+ *
7
+ * There is no plain-`node` way to run this file from the source tree: the
8
+ * workspace packages export `./src/index.ts`, and Node's type stripping does
9
+ * NOT rewrite the relative `./x.js` specifiers inside them, so the import of
10
+ * `./index.js` here fails with ERR_MODULE_NOT_FOUND. Run the published bundle
11
+ * instead:
12
+ *
13
+ * pnpm dist && node apps/cli/dist/bin/boombot.js gateway --no-browser
14
+ *
15
+ * or in-process via the CLI: `boombot gateway` (also `boombot serve`).
16
+ * For a source-tree entry, set BOOMBOT_GATEWAY_ENTRY=<path> to a loadable
17
+ * bundle — that override is the only supported escape hatch.
18
+ */
19
+ import { startGateway } from './index.js';
20
+ void startGateway().catch((error) => {
21
+ console.error('[gateway] fatal boot error:', error instanceof Error ? error.message : String(error));
22
+ process.exit(1);
23
+ });
@@ -0,0 +1,354 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { createServer as createHttpServer, } from 'node:http';
3
+ import { createEnvelope, parseEnvelope, ProtocolError, WIRE_VERSION, } from '@boombot/protocol';
4
+ import { checkAuth } from './auth.js';
5
+ import { handleSSE, handleTurnSSE } from './events.js';
6
+ import { serveStatic } from './static.js';
7
+ /**
8
+ * Gateway HTTP server (node:http, no framework).
9
+ *
10
+ * Routes:
11
+ * - `GET /` and other non-API paths — the bundled web UI (`dist/web/`) when
12
+ * present, with SPA fallback to `index.html` (see `static.ts`). Falls
13
+ * through to 404 in API-only dev mode.
14
+ * - `GET /healthz` — liveness, no auth: `{ ok, version, wireVersion }`.
15
+ * - `GET /v1/events` — SSE stream of `StreamEvent`s. Auth required.
16
+ * - `GET /v1/turns/:turnId/events` — per-turn SSE stream (web chat). Auth required.
17
+ * - `POST /v1/commands` — command envelope dispatch. Auth required,
18
+ * body limited to 1 MiB.
19
+ *
20
+ * Errors use the flat error body the web client parses:
21
+ * `{ error: { code, message, requestId?, details? } }` with the matching
22
+ * HTTP status (400 protocol errors, 401 auth, 404/405 routing, 413 body too
23
+ * large, 500 unexpected). Request logs never include headers or bodies.
24
+ */
25
+ /** Max JSON body accepted on `POST /v1/commands` (1 MiB). */
26
+ export const MAX_BODY_BYTES = 1_048_576;
27
+ function readGatewayVersion() {
28
+ try {
29
+ const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');
30
+ const parsed = JSON.parse(raw);
31
+ if (typeof parsed === 'object' &&
32
+ parsed !== null &&
33
+ 'version' in parsed &&
34
+ typeof parsed.version === 'string') {
35
+ return parsed.version;
36
+ }
37
+ }
38
+ catch {
39
+ // Fall through to the fallback below.
40
+ }
41
+ return '0.0.0';
42
+ }
43
+ /** Gateway package version, surfaced on `GET /healthz`. */
44
+ export const GATEWAY_VERSION = readGatewayVersion();
45
+ class BodyTooLargeError extends Error {
46
+ constructor() {
47
+ super(`Request body exceeds ${MAX_BODY_BYTES} bytes`);
48
+ this.name = 'BodyTooLargeError';
49
+ }
50
+ }
51
+ function sendJson(res, status, body) {
52
+ const text = JSON.stringify(body);
53
+ res.writeHead(status, {
54
+ 'Content-Type': 'application/json; charset=utf-8',
55
+ 'Content-Length': Buffer.byteLength(text),
56
+ });
57
+ res.end(text);
58
+ }
59
+ function sendOAuthPage(res, status, success) {
60
+ const title = success ? 'Zalo connected' : 'Zalo connection failed';
61
+ const body = `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>${title}</title><style>body{font:16px system-ui;margin:3rem;color:#172033}main{max-width:32rem;margin:auto}h1{font-size:1.4rem}</style></head><body><main><h1>${title}</h1><p>${success ? 'You can close this window and return to BoomBot.' : 'Return to BoomBot and start the connection again.'}</p></main>${success ? '<script>setTimeout(()=>window.close(),800)</script>' : ''}</body></html>`;
62
+ res.writeHead(status, {
63
+ 'Content-Type': 'text/html; charset=utf-8',
64
+ 'Content-Length': Buffer.byteLength(body),
65
+ 'Content-Security-Policy': "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'",
66
+ 'Referrer-Policy': 'no-referrer',
67
+ 'X-Content-Type-Options': 'nosniff',
68
+ });
69
+ res.end(body);
70
+ }
71
+ function sendError(res, status, code, message, options) {
72
+ const error = {
73
+ code,
74
+ message,
75
+ };
76
+ if (options?.requestId !== undefined)
77
+ error.requestId = options.requestId;
78
+ if (options?.details !== undefined)
79
+ error.details = options.details;
80
+ sendJson(res, status, { error });
81
+ }
82
+ function protocolStatus(code) {
83
+ switch (code) {
84
+ case 'INVALID_ENVELOPE':
85
+ case 'VERSION_MISMATCH':
86
+ case 'UNKNOWN_COMMAND':
87
+ case 'INVALID_PAYLOAD':
88
+ case 'INVALID_EVENT':
89
+ return 400;
90
+ case 'SESSION_NOT_FOUND':
91
+ return 404;
92
+ case 'NOT_CONFIGURED':
93
+ return 503;
94
+ }
95
+ }
96
+ function readBody(req) {
97
+ return new Promise((resolve, reject) => {
98
+ const chunks = [];
99
+ let size = 0;
100
+ let settled = false;
101
+ req.on('data', (chunk) => {
102
+ if (settled)
103
+ return;
104
+ size += chunk.length;
105
+ if (size > MAX_BODY_BYTES) {
106
+ settled = true;
107
+ reject(new BodyTooLargeError());
108
+ // Pause the upload; the 413 response is sent by the caller, and the
109
+ // stream is destroyed only after the response has been flushed
110
+ // (destroying here would kill the socket before the client reads it).
111
+ req.pause();
112
+ return;
113
+ }
114
+ chunks.push(chunk);
115
+ });
116
+ req.on('end', () => {
117
+ if (!settled) {
118
+ settled = true;
119
+ resolve(Buffer.concat(chunks));
120
+ }
121
+ });
122
+ req.on('error', (err) => {
123
+ if (!settled) {
124
+ settled = true;
125
+ reject(err);
126
+ }
127
+ });
128
+ });
129
+ }
130
+ function methodNotAllowed(ctx, res, method, path) {
131
+ ctx.log('warn', 'request', { method, path, status: 405 });
132
+ sendError(res, 405, 'METHOD_NOT_ALLOWED', `Method ${method} not allowed for ${path}`);
133
+ }
134
+ async function handleCommand(req, res, ctx) {
135
+ let requestId;
136
+ try {
137
+ const raw = (await readBody(req)).toString('utf8');
138
+ let json;
139
+ try {
140
+ json = raw.length === 0 ? undefined : JSON.parse(raw);
141
+ }
142
+ catch {
143
+ throw new ProtocolError('INVALID_ENVELOPE', 'Request body is not valid JSON');
144
+ }
145
+ const envelope = parseEnvelope(json);
146
+ requestId = envelope.requestId;
147
+ const result = await ctx.registry.dispatch(envelope.type, ctx, envelope.payload, {
148
+ requestId,
149
+ });
150
+ sendJson(res, 200, createEnvelope(envelope.type, result, requestId));
151
+ ctx.log('debug', 'request', {
152
+ method: 'POST',
153
+ path: '/v1/commands',
154
+ status: 200,
155
+ type: envelope.type,
156
+ requestId,
157
+ });
158
+ }
159
+ catch (error) {
160
+ if (error instanceof BodyTooLargeError) {
161
+ ctx.log('warn', 'request', { method: 'POST', path: '/v1/commands', status: 413 });
162
+ sendError(res, 413, 'PAYLOAD_TOO_LARGE', error.message, { requestId });
163
+ // Tear down the (paused) upload stream only after the 413 has flushed.
164
+ res.on('finish', () => req.destroy());
165
+ return;
166
+ }
167
+ if (error instanceof ProtocolError) {
168
+ const status = protocolStatus(error.code);
169
+ ctx.log('warn', 'request', {
170
+ method: 'POST',
171
+ path: '/v1/commands',
172
+ status,
173
+ code: error.code,
174
+ requestId,
175
+ });
176
+ sendError(res, status, error.code, error.message, {
177
+ requestId,
178
+ details: error.details,
179
+ });
180
+ return;
181
+ }
182
+ // Unexpected handler failure: generic message on the wire, details in the log only.
183
+ ctx.log('error', 'command handler failed', {
184
+ requestId,
185
+ message: error instanceof Error ? error.message : String(error),
186
+ });
187
+ sendError(res, 500, 'INTERNAL_ERROR', 'Internal server error', { requestId });
188
+ }
189
+ }
190
+ async function handleChannelWebhook(req, res, ctx, channel, method, query) {
191
+ if (ctx.channelService === undefined) {
192
+ sendError(res, 503, 'NOT_CONFIGURED', 'Channel service is unavailable');
193
+ return;
194
+ }
195
+ try {
196
+ const response = await ctx.channelService.handleWebhook(channel, {
197
+ method,
198
+ rawBody: method === 'POST' ? await readBody(req) : Buffer.alloc(0),
199
+ headers: req.headers,
200
+ query,
201
+ });
202
+ const body = response.body ?? '';
203
+ res.writeHead(response.status, {
204
+ 'Content-Type': response.contentType ?? 'text/plain; charset=utf-8',
205
+ 'Content-Length': Buffer.byteLength(body),
206
+ });
207
+ res.end(body);
208
+ ctx.log('debug', 'channel webhook', { channel, method, status: response.status });
209
+ }
210
+ catch (error) {
211
+ if (error instanceof BodyTooLargeError) {
212
+ sendError(res, 413, 'PAYLOAD_TOO_LARGE', error.message);
213
+ res.on('finish', () => req.destroy());
214
+ return;
215
+ }
216
+ ctx.log('error', 'channel webhook failed', {
217
+ channel,
218
+ message: error instanceof Error ? error.message : String(error),
219
+ });
220
+ sendError(res, 500, 'INTERNAL_ERROR', 'Internal server error');
221
+ }
222
+ }
223
+ async function handleRequest(req, res, ctx) {
224
+ const url = new URL(req.url ?? '/', 'http://localhost');
225
+ const path = url.pathname;
226
+ const method = (req.method ?? 'GET').toUpperCase();
227
+ if (path === '/healthz') {
228
+ if (method !== 'GET') {
229
+ methodNotAllowed(ctx, res, method, path);
230
+ return;
231
+ }
232
+ sendJson(res, 200, { ok: true, version: GATEWAY_VERSION, wireVersion: WIRE_VERSION });
233
+ ctx.log('debug', 'request', { method, path, status: 200 });
234
+ return;
235
+ }
236
+ if (path === '/v1/channels/zalo/oauth/callback') {
237
+ if (method !== 'GET') {
238
+ methodNotAllowed(ctx, res, method, path);
239
+ return;
240
+ }
241
+ if (ctx.channelService === undefined) {
242
+ sendOAuthPage(res, 503, false);
243
+ return;
244
+ }
245
+ try {
246
+ await ctx.channelService.completeZaloOAuth(url.searchParams);
247
+ sendOAuthPage(res, 200, true);
248
+ ctx.log('info', 'zalo OAuth callback completed', { path });
249
+ }
250
+ catch (error) {
251
+ ctx.log('warn', 'zalo OAuth callback failed', {
252
+ path,
253
+ error: error instanceof Error ? error.message : String(error),
254
+ });
255
+ sendOAuthPage(res, 400, false);
256
+ }
257
+ return;
258
+ }
259
+ const webhookMatch = /^\/v1\/channels\/(slack|discord|whatsapp|messenger)\/webhook$/.exec(path);
260
+ if (webhookMatch !== null) {
261
+ if (method !== 'POST' && !(method === 'GET' && (webhookMatch[1] === 'whatsapp' || webhookMatch[1] === 'messenger'))) {
262
+ methodNotAllowed(ctx, res, method, path);
263
+ return;
264
+ }
265
+ await handleChannelWebhook(req, res, ctx, webhookMatch[1] ?? '', method, url.searchParams);
266
+ return;
267
+ }
268
+ if (path === '/v1/events') {
269
+ if (method !== 'GET') {
270
+ methodNotAllowed(ctx, res, method, path);
271
+ return;
272
+ }
273
+ const auth = checkAuth(req, ctx.config);
274
+ if (!auth.ok) {
275
+ ctx.log('warn', 'request', { method, path, status: 401, code: auth.code });
276
+ sendError(res, 401, auth.code, auth.message);
277
+ return;
278
+ }
279
+ handleSSE(req, res);
280
+ ctx.log('info', 'sse connected', { path });
281
+ return;
282
+ }
283
+ // Per-turn SSE stream for the web chat view: GET /v1/turns/:turnId/events.
284
+ const turnEventsMatch = /^\/v1\/turns\/([^/]+)\/events$/.exec(path);
285
+ if (turnEventsMatch !== null) {
286
+ if (method !== 'GET') {
287
+ methodNotAllowed(ctx, res, method, path);
288
+ return;
289
+ }
290
+ const auth = checkAuth(req, ctx.config);
291
+ if (!auth.ok) {
292
+ ctx.log('warn', 'request', { method, path, status: 401, code: auth.code });
293
+ sendError(res, 401, auth.code, auth.message);
294
+ return;
295
+ }
296
+ const turnId = decodeURIComponent(turnEventsMatch[1] ?? '');
297
+ if (turnId.length === 0) {
298
+ sendError(res, 400, 'INVALID_PAYLOAD', 'Missing turn id');
299
+ return;
300
+ }
301
+ handleTurnSSE(req, res, turnId, () => ctx.turnService?.getTerminalEvent?.(turnId), () => ctx.turnService?.getProgressEvents?.(turnId) ?? []);
302
+ ctx.log('info', 'sse connected', { path: '/v1/turns/:turnId/events', turnId });
303
+ return;
304
+ }
305
+ if (path === '/v1/commands') {
306
+ if (method !== 'POST') {
307
+ methodNotAllowed(ctx, res, method, path);
308
+ return;
309
+ }
310
+ const auth = checkAuth(req, ctx.config);
311
+ if (!auth.ok) {
312
+ ctx.log('warn', 'request', { method, path, status: 401, code: auth.code });
313
+ sendError(res, 401, auth.code, auth.message);
314
+ return;
315
+ }
316
+ await handleCommand(req, res, ctx);
317
+ return;
318
+ }
319
+ // Bundled web UI (`dist/web/`, zero-dependency static serving with SPA
320
+ // fallback). Falls through when the assets are absent (API-only dev mode),
321
+ // so the dev workflow is untouched.
322
+ if (await serveStatic(req, res, ctx.log)) {
323
+ return;
324
+ }
325
+ ctx.log('warn', 'request', { method, path, status: 404 });
326
+ sendError(res, 404, 'NOT_FOUND', `Unknown path: ${path}`);
327
+ }
328
+ /**
329
+ * Create (but do not listen on) the gateway HTTP server. The caller owns
330
+ * `listen()` / `close()`; `main.ts` wires the `ServiceContext` and starts it.
331
+ */
332
+ export function createGatewayServer(ctx) {
333
+ // P1-2: re-announce HITL approvals still `pending` from the previous
334
+ // process, before the server starts listening. The turn service retains
335
+ // them in its per-turn progress replay, so a client opening
336
+ // `GET /v1/turns/:turnId/events` after boot still sees the pending
337
+ // approval instead of a silent timeout. No turn service (tests, API-only
338
+ // boot) → no-op.
339
+ ctx.turnService?.reannouncePendingApprovals?.();
340
+ const server = createHttpServer((req, res) => {
341
+ void handleRequest(req, res, ctx).catch((error) => {
342
+ ctx.log('error', 'unhandled request error', {
343
+ message: error instanceof Error ? error.message : String(error),
344
+ });
345
+ if (!res.headersSent) {
346
+ sendError(res, 500, 'INTERNAL_ERROR', 'Internal server error');
347
+ }
348
+ else {
349
+ res.destroy();
350
+ }
351
+ });
352
+ });
353
+ return server;
354
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Dynamic Provider Context Limit Resolver.
3
+ *
4
+ * Resolves the accurate token context window and character bounds for any active
5
+ * provider and model dynamically. Eliminates hardcoded limits so providers with
6
+ * large contexts (e.g. 257k for CommandCode/anti, 200k for Claude, 1M for Gemini)
7
+ * utilize their full capacity while preventing overflow on smaller models.
8
+ */
9
+ export function resolveProviderContextLimits(provider, modelName) {
10
+ // 1. Explicit environment variable override
11
+ const envLimit = process.env['BOOMBOT_MAX_CONTEXT_TOKENS'];
12
+ if (envLimit && !isNaN(Number(envLimit))) {
13
+ const tokens = Math.max(4_000, Number(envLimit));
14
+ return {
15
+ maxContextTokens: tokens,
16
+ maxContextChars: tokens * 4,
17
+ triggerThreshold: 0.75,
18
+ hotZoneRounds: 4,
19
+ };
20
+ }
21
+ // 2. Explicit provider extra configurations
22
+ if (typeof provider?.extra?.['contextWindow'] === 'number') {
23
+ const tokens = Math.max(4_000, provider.extra['contextWindow']);
24
+ return {
25
+ maxContextTokens: tokens,
26
+ maxContextChars: tokens * 4,
27
+ triggerThreshold: 0.75,
28
+ hotZoneRounds: 4,
29
+ };
30
+ }
31
+ if (typeof provider?.extra?.['maxTokens'] === 'number' && provider.extra['maxTokens'] > 16_000) {
32
+ const tokens = provider.extra['maxTokens'];
33
+ return {
34
+ maxContextTokens: tokens,
35
+ maxContextChars: tokens * 4,
36
+ triggerThreshold: 0.75,
37
+ hotZoneRounds: 4,
38
+ };
39
+ }
40
+ const model = (modelName || provider?.model || '').toLowerCase();
41
+ const kind = (provider?.kind || '').toLowerCase();
42
+ // 3. Model & Provider heuristic mapping
43
+ let tokens = 128_000;
44
+ if (model.includes('anti')) {
45
+ // CommandCode 9Router anti instance
46
+ tokens = 257_000;
47
+ }
48
+ else if (model.includes('gemini') || kind === 'google') {
49
+ tokens = 1_000_000;
50
+ }
51
+ else if (model.includes('claude') || kind === 'anthropic') {
52
+ tokens = 200_000;
53
+ }
54
+ else if (model.includes('deepseek') || kind === 'deepseek') {
55
+ tokens = 128_000;
56
+ }
57
+ else if (model.includes('gpt-4o') || model.includes('o1') || model.includes('o3') || kind === 'openai') {
58
+ tokens = 128_000;
59
+ }
60
+ else if (model.includes('qwen') || kind === 'qwen') {
61
+ tokens = 128_000;
62
+ }
63
+ else if (model.includes('mistral') || model.includes('codestral') || kind === 'mistral') {
64
+ tokens = 128_000;
65
+ }
66
+ else if (kind === 'ollama') {
67
+ tokens = 32_768;
68
+ }
69
+ return {
70
+ maxContextTokens: tokens,
71
+ maxContextChars: tokens * 4,
72
+ triggerThreshold: 0.75,
73
+ hotZoneRounds: 4,
74
+ };
75
+ }