@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.
- package/README.md +69 -3
- package/dist/LICENSE +21 -0
- package/dist/bin/boombot.js +16 -0
- package/dist/cli/api-key.js +123 -0
- package/dist/cli/bin-bun.js +17 -0
- package/dist/cli/bin.js +34 -0
- package/dist/cli/cli/cli-error.js +61 -0
- package/dist/cli/cli/dispatch.js +138 -0
- package/dist/cli/cli/help.js +83 -0
- package/dist/cli/cli/parser.js +89 -0
- package/dist/cli/cli/registry.js +185 -0
- package/dist/cli/cli/spec.js +41 -0
- package/dist/cli/cli/suggest.js +125 -0
- package/dist/cli/cli/version.js +30 -0
- package/dist/cli/cli/vocabulary.js +87 -0
- package/dist/cli/commands/doctor.js +365 -0
- package/dist/cli/commands/gateway.js +290 -0
- package/dist/cli/commands/migrate.js +270 -0
- package/dist/cli/commands/plugin.js +97 -0
- package/dist/cli/commands/setup.js +244 -0
- package/dist/cli/config-file.js +133 -0
- package/dist/cli/master-key.js +78 -0
- package/dist/cli/open-browser.js +59 -0
- package/dist/cli/web-assets.js +58 -0
- package/dist/gateway/auth.js +46 -0
- package/dist/gateway/config-format.js +202 -0
- package/dist/gateway/config.js +427 -0
- package/dist/gateway/context.js +1 -0
- package/dist/gateway/env-file.js +129 -0
- package/dist/gateway/events.js +172 -0
- package/dist/gateway/guard/tagging.js +505 -0
- package/dist/gateway/handlers/index.js +66 -0
- package/dist/gateway/handlers/memory.js +54 -0
- package/dist/gateway/handlers/providers.js +73 -0
- package/dist/gateway/handlers/registry.js +39 -0
- package/dist/gateway/handlers/sessions.js +188 -0
- package/dist/gateway/handlers/system.js +12 -0
- package/dist/gateway/handlers/tasks.js +191 -0
- package/dist/gateway/handlers/turn.js +100 -0
- package/dist/gateway/index.js +126 -0
- package/dist/gateway/main.js +23 -0
- package/dist/gateway/server.js +354 -0
- package/dist/gateway/services/context-limits.js +75 -0
- package/dist/gateway/services/history-normalizer.js +42 -0
- package/dist/gateway/services/image-pipeline.js +56 -0
- package/dist/gateway/services/key-roulette-client.js +43 -0
- package/dist/gateway/services/llm-client.js +593 -0
- package/dist/gateway/services/llm-decoder.js +200 -0
- package/dist/gateway/services/local-fallback.js +135 -0
- package/dist/gateway/services/memory.js +511 -0
- package/dist/gateway/services/persistent-memory.js +196 -0
- package/dist/gateway/services/providers.js +44 -0
- package/dist/gateway/services/tasks.js +237 -0
- package/dist/gateway/services/verification.js +124 -0
- package/dist/gateway/services/vision-payload.js +48 -0
- package/dist/gateway/services.js +257 -0
- package/dist/gateway/session-snapshot.js +19 -0
- package/dist/gateway/sessions.js +701 -0
- package/dist/gateway/static.js +239 -0
- package/dist/gateway/turns/clarify-tool.js +57 -0
- package/dist/gateway/turns/cronjob-tool.js +96 -0
- package/dist/gateway/turns/deferred-tools.js +154 -0
- package/dist/gateway/turns/execute-code-tool.js +84 -0
- package/dist/gateway/turns/file-tool-defs.js +178 -0
- package/dist/gateway/turns/file-tool-ops.js +178 -0
- package/dist/gateway/turns/file-tool-scan.js +182 -0
- package/dist/gateway/turns/file-tool.js +302 -0
- package/dist/gateway/turns/index.js +416 -0
- package/dist/gateway/turns/jev-middleware.js +91 -0
- package/dist/gateway/turns/local-reply.js +156 -0
- package/dist/gateway/turns/mcp-client.js +643 -0
- package/dist/gateway/turns/memory-tool.js +171 -0
- package/dist/gateway/turns/middleware.js +96 -0
- package/dist/gateway/turns/python-core.js +397 -0
- package/dist/gateway/turns/routing/index.js +3 -0
- package/dist/gateway/turns/routing/intent-classifier.js +60 -0
- package/dist/gateway/turns/routing/planner-adapter.js +91 -0
- package/dist/gateway/turns/routing/types.js +1 -0
- package/dist/gateway/turns/runtime-deps.js +228 -0
- package/dist/gateway/turns/self-config-tool.js +277 -0
- package/dist/gateway/turns/service-types.js +11 -0
- package/dist/gateway/turns/service.js +820 -0
- package/dist/gateway/turns/session-adapter.js +158 -0
- package/dist/gateway/turns/session-tool.js +49 -0
- package/dist/gateway/turns/shell-tool.js +190 -0
- package/dist/gateway/turns/skill-tool.js +239 -0
- package/dist/gateway/turns/spillover.js +201 -0
- package/dist/gateway/turns/subagent-tool.js +140 -0
- package/dist/gateway/turns/system-prompt.js +121 -0
- package/dist/gateway/turns/tool-schema.js +90 -0
- package/dist/gateway/turns/turn-utils.js +58 -0
- package/dist/gateway/turns/vision-tool.js +120 -0
- package/dist/gateway/types.js +1 -0
- package/dist/native/win32-x64/boombot-native-host.exe +0 -0
- package/dist/node_modules/@boombot/channels/handlers.d.ts +9 -0
- package/dist/node_modules/@boombot/channels/handlers.js +109 -0
- package/dist/node_modules/@boombot/channels/index.d.ts +12 -0
- package/dist/node_modules/@boombot/channels/index.js +12 -0
- package/dist/node_modules/@boombot/channels/package.json +9 -0
- package/dist/node_modules/@boombot/channels/service.d.ts +62 -0
- package/dist/node_modules/@boombot/channels/service.js +608 -0
- package/dist/node_modules/@boombot/channels/tool.d.ts +10 -0
- package/dist/node_modules/@boombot/channels/tool.js +46 -0
- package/dist/node_modules/@boombot/channels/transports/common/dedup.d.ts +17 -0
- package/dist/node_modules/@boombot/channels/transports/common/dedup.js +42 -0
- package/dist/node_modules/@boombot/channels/transports/common/handoff.d.ts +19 -0
- package/dist/node_modules/@boombot/channels/transports/common/handoff.js +32 -0
- package/dist/node_modules/@boombot/channels/transports/common/index.d.ts +3 -0
- package/dist/node_modules/@boombot/channels/transports/common/index.js +3 -0
- package/dist/node_modules/@boombot/channels/transports/common/types.d.ts +99 -0
- package/dist/node_modules/@boombot/channels/transports/common/types.js +54 -0
- package/dist/node_modules/@boombot/channels/transports/common.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/common.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/dedup/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/dedup/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/dedup.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/dedup.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/discord/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/discord/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/discord/transport.d.ts +36 -0
- package/dist/node_modules/@boombot/channels/transports/discord/transport.js +199 -0
- package/dist/node_modules/@boombot/channels/transports/discord.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/discord.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/handoff.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/handoff.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/messenger/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/messenger/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/messenger/transport.d.ts +34 -0
- package/dist/node_modules/@boombot/channels/transports/messenger/transport.js +180 -0
- package/dist/node_modules/@boombot/channels/transports/messenger.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/messenger.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/slack/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/slack/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/slack/transport.d.ts +35 -0
- package/dist/node_modules/@boombot/channels/transports/slack/transport.js +183 -0
- package/dist/node_modules/@boombot/channels/transports/slack.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/slack.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/streamer/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/streamer/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/streamer/streamer.d.ts +31 -0
- package/dist/node_modules/@boombot/channels/transports/streamer/streamer.js +141 -0
- package/dist/node_modules/@boombot/channels/transports/streamer.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/streamer.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/telegram/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/telegram/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/telegram/transport.d.ts +75 -0
- package/dist/node_modules/@boombot/channels/transports/telegram/transport.js +395 -0
- package/dist/node_modules/@boombot/channels/transports/telegram.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/telegram.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok/transport.d.ts +27 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok/transport.js +97 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/tiktok.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp/index.d.ts +1 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp/index.js +1 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.d.ts +38 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.js +189 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/whatsapp.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/index.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/index.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/oa.d.ts +28 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/oa.js +94 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/personal.d.ts +106 -0
- package/dist/node_modules/@boombot/channels/transports/zalo/personal.js +171 -0
- package/dist/node_modules/@boombot/channels/transports/zalo-personal.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo-personal.js +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo.d.ts +2 -0
- package/dist/node_modules/@boombot/channels/transports/zalo.js +2 -0
- package/dist/node_modules/@boombot/core/agent-core/index.d.ts +12 -0
- package/dist/node_modules/@boombot/core/agent-core/index.js +12 -0
- package/dist/node_modules/@boombot/core/agent-core/middleware.d.ts +60 -0
- package/dist/node_modules/@boombot/core/agent-core/middleware.js +152 -0
- package/dist/node_modules/@boombot/core/agent-core/routing.d.ts +128 -0
- package/dist/node_modules/@boombot/core/agent-core/routing.js +437 -0
- package/dist/node_modules/@boombot/core/agent-core/runtime-deps.d.ts +88 -0
- package/dist/node_modules/@boombot/core/agent-core/runtime-deps.js +8 -0
- package/dist/node_modules/@boombot/core/agent-core/tool-errors.d.ts +44 -0
- package/dist/node_modules/@boombot/core/agent-core/tool-errors.js +60 -0
- package/dist/node_modules/@boombot/core/agent-core/turn-loop.d.ts +21 -0
- package/dist/node_modules/@boombot/core/agent-core/turn-loop.js +561 -0
- package/dist/node_modules/@boombot/core/agent-core/types.d.ts +189 -0
- package/dist/node_modules/@boombot/core/agent-core/types.js +7 -0
- package/dist/node_modules/@boombot/core/compaction/compactor.d.ts +19 -0
- package/dist/node_modules/@boombot/core/compaction/compactor.js +127 -0
- package/dist/node_modules/@boombot/core/compaction/estimator.d.ts +10 -0
- package/dist/node_modules/@boombot/core/compaction/estimator.js +48 -0
- package/dist/node_modules/@boombot/core/compaction/index.d.ts +3 -0
- package/dist/node_modules/@boombot/core/compaction/index.js +3 -0
- package/dist/node_modules/@boombot/core/compaction/types.d.ts +31 -0
- package/dist/node_modules/@boombot/core/compaction/types.js +7 -0
- package/dist/node_modules/@boombot/core/index.d.ts +9 -0
- package/dist/node_modules/@boombot/core/index.js +9 -0
- package/dist/node_modules/@boombot/core/jev/index.d.ts +2 -0
- package/dist/node_modules/@boombot/core/jev/index.js +2 -0
- package/dist/node_modules/@boombot/core/jev/jev.d.ts +30 -0
- package/dist/node_modules/@boombot/core/jev/jev.js +164 -0
- package/dist/node_modules/@boombot/core/jev/types.d.ts +22 -0
- package/dist/node_modules/@boombot/core/jev/types.js +1 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/budget.d.ts +63 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/budget.js +94 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.d.ts +152 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.js +318 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/index.d.ts +12 -0
- package/dist/node_modules/@boombot/core/memory/consolidation/index.js +12 -0
- package/dist/node_modules/@boombot/core/memory/curation.d.ts +86 -0
- package/dist/node_modules/@boombot/core/memory/curation.js +120 -0
- package/dist/node_modules/@boombot/core/memory/errors.d.ts +12 -0
- package/dist/node_modules/@boombot/core/memory/errors.js +20 -0
- package/dist/node_modules/@boombot/core/memory/hybrid-search.d.ts +29 -0
- package/dist/node_modules/@boombot/core/memory/hybrid-search.js +52 -0
- package/dist/node_modules/@boombot/core/memory/index.d.ts +23 -0
- package/dist/node_modules/@boombot/core/memory/index.js +23 -0
- package/dist/node_modules/@boombot/core/memory/indexer.d.ts +47 -0
- package/dist/node_modules/@boombot/core/memory/indexer.js +138 -0
- package/dist/node_modules/@boombot/core/memory/lifecycle.d.ts +12 -0
- package/dist/node_modules/@boombot/core/memory/lifecycle.js +66 -0
- package/dist/node_modules/@boombot/core/memory/provider.d.ts +84 -0
- package/dist/node_modules/@boombot/core/memory/provider.js +117 -0
- package/dist/node_modules/@boombot/core/memory/recall.d.ts +7 -0
- package/dist/node_modules/@boombot/core/memory/recall.js +111 -0
- package/dist/node_modules/@boombot/core/memory/scope-resolver.d.ts +27 -0
- package/dist/node_modules/@boombot/core/memory/scope-resolver.js +60 -0
- package/dist/node_modules/@boombot/core/memory/search.d.ts +37 -0
- package/dist/node_modules/@boombot/core/memory/search.js +158 -0
- package/dist/node_modules/@boombot/core/memory/store.d.ts +60 -0
- package/dist/node_modules/@boombot/core/memory/store.js +289 -0
- package/dist/node_modules/@boombot/core/memory/types.d.ts +121 -0
- package/dist/node_modules/@boombot/core/memory/types.js +21 -0
- package/dist/node_modules/@boombot/core/memory/vector-index.d.ts +34 -0
- package/dist/node_modules/@boombot/core/memory/vector-index.js +65 -0
- package/dist/node_modules/@boombot/core/package.json +9 -0
- package/dist/node_modules/@boombot/core/reflection/classifier.d.ts +13 -0
- package/dist/node_modules/@boombot/core/reflection/classifier.js +77 -0
- package/dist/node_modules/@boombot/core/reflection/index.d.ts +2 -0
- package/dist/node_modules/@boombot/core/reflection/index.js +2 -0
- package/dist/node_modules/@boombot/core/reflection/types.d.ts +13 -0
- package/dist/node_modules/@boombot/core/reflection/types.js +4 -0
- package/dist/node_modules/@boombot/core/research/config.d.ts +89 -0
- package/dist/node_modules/@boombot/core/research/config.js +206 -0
- package/dist/node_modules/@boombot/core/research/crawl.d.ts +36 -0
- package/dist/node_modules/@boombot/core/research/crawl.js +179 -0
- package/dist/node_modules/@boombot/core/research/factory.d.ts +26 -0
- package/dist/node_modules/@boombot/core/research/factory.js +46 -0
- package/dist/node_modules/@boombot/core/research/http.d.ts +87 -0
- package/dist/node_modules/@boombot/core/research/http.js +250 -0
- package/dist/node_modules/@boombot/core/research/index.d.ts +17 -0
- package/dist/node_modules/@boombot/core/research/index.js +10 -0
- package/dist/node_modules/@boombot/core/research/orchestrator.d.ts +113 -0
- package/dist/node_modules/@boombot/core/research/orchestrator.js +252 -0
- package/dist/node_modules/@boombot/core/research/parse/docx.d.ts +24 -0
- package/dist/node_modules/@boombot/core/research/parse/docx.js +183 -0
- package/dist/node_modules/@boombot/core/research/parse/guards.d.ts +89 -0
- package/dist/node_modules/@boombot/core/research/parse/guards.js +171 -0
- package/dist/node_modules/@boombot/core/research/parse/index.d.ts +68 -0
- package/dist/node_modules/@boombot/core/research/parse/index.js +219 -0
- package/dist/node_modules/@boombot/core/research/parse/pdf.d.ts +38 -0
- package/dist/node_modules/@boombot/core/research/parse/pdf.js +567 -0
- package/dist/node_modules/@boombot/core/research/providers/arxiv.d.ts +9 -0
- package/dist/node_modules/@boombot/core/research/providers/arxiv.js +72 -0
- package/dist/node_modules/@boombot/core/research/providers/brave.d.ts +11 -0
- package/dist/node_modules/@boombot/core/research/providers/brave.js +36 -0
- package/dist/node_modules/@boombot/core/research/providers/duckduckgo.d.ts +9 -0
- package/dist/node_modules/@boombot/core/research/providers/duckduckgo.js +78 -0
- package/dist/node_modules/@boombot/core/research/providers/exa.d.ts +11 -0
- package/dist/node_modules/@boombot/core/research/providers/exa.js +34 -0
- package/dist/node_modules/@boombot/core/research/providers/firecrawl.d.ts +16 -0
- package/dist/node_modules/@boombot/core/research/providers/firecrawl.js +47 -0
- package/dist/node_modules/@boombot/core/research/providers/index.d.ts +17 -0
- package/dist/node_modules/@boombot/core/research/providers/index.js +11 -0
- package/dist/node_modules/@boombot/core/research/providers/jina.d.ts +13 -0
- package/dist/node_modules/@boombot/core/research/providers/jina.js +114 -0
- package/dist/node_modules/@boombot/core/research/providers/openalex.d.ts +14 -0
- package/dist/node_modules/@boombot/core/research/providers/openalex.js +66 -0
- package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.d.ts +9 -0
- package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.js +56 -0
- package/dist/node_modules/@boombot/core/research/providers/tavily.d.ts +11 -0
- package/dist/node_modules/@boombot/core/research/providers/tavily.js +35 -0
- package/dist/node_modules/@boombot/core/research/providers/wikipedia.d.ts +12 -0
- package/dist/node_modules/@boombot/core/research/providers/wikipedia.js +47 -0
- package/dist/node_modules/@boombot/core/research/tools.d.ts +27 -0
- package/dist/node_modules/@boombot/core/research/tools.js +251 -0
- package/dist/node_modules/@boombot/core/research/types.d.ts +133 -0
- package/dist/node_modules/@boombot/core/research/types.js +8 -0
- package/dist/node_modules/@boombot/core/research/wiring.d.ts +25 -0
- package/dist/node_modules/@boombot/core/research/wiring.js +51 -0
- package/dist/node_modules/@boombot/core/scheduler/cron.d.ts +34 -0
- package/dist/node_modules/@boombot/core/scheduler/cron.js +147 -0
- package/dist/node_modules/@boombot/core/scheduler/evaluator.d.ts +42 -0
- package/dist/node_modules/@boombot/core/scheduler/evaluator.js +148 -0
- package/dist/node_modules/@boombot/core/scheduler/index.d.ts +15 -0
- package/dist/node_modules/@boombot/core/scheduler/index.js +15 -0
- package/dist/node_modules/@boombot/core/scheduler/registry.d.ts +81 -0
- package/dist/node_modules/@boombot/core/scheduler/registry.js +263 -0
- package/dist/node_modules/@boombot/core/scheduler/runner.d.ts +59 -0
- package/dist/node_modules/@boombot/core/scheduler/runner.js +257 -0
- package/dist/node_modules/@boombot/core/scheduler/store.d.ts +150 -0
- package/dist/node_modules/@boombot/core/scheduler/store.js +526 -0
- package/dist/node_modules/@boombot/core/scheduler/timezone.d.ts +35 -0
- package/dist/node_modules/@boombot/core/scheduler/timezone.js +96 -0
- package/dist/node_modules/@boombot/core/scheduler/types.d.ts +157 -0
- package/dist/node_modules/@boombot/core/scheduler/types.js +89 -0
- package/dist/node_modules/@boombot/core/task-runner/index.d.ts +7 -0
- package/dist/node_modules/@boombot/core/task-runner/index.js +5 -0
- package/dist/node_modules/@boombot/core/task-runner/planner.d.ts +37 -0
- package/dist/node_modules/@boombot/core/task-runner/planner.js +154 -0
- package/dist/node_modules/@boombot/core/task-runner/runner.d.ts +8 -0
- package/dist/node_modules/@boombot/core/task-runner/runner.js +564 -0
- package/dist/node_modules/@boombot/core/task-runner/store.d.ts +28 -0
- package/dist/node_modules/@boombot/core/task-runner/store.js +126 -0
- package/dist/node_modules/@boombot/core/task-runner/types.d.ts +138 -0
- package/dist/node_modules/@boombot/core/task-runner/types.js +11 -0
- package/dist/node_modules/@boombot/core/workflow/dag.d.ts +16 -0
- package/dist/node_modules/@boombot/core/workflow/dag.js +109 -0
- package/dist/node_modules/@boombot/core/workflow/engine.d.ts +34 -0
- package/dist/node_modules/@boombot/core/workflow/engine.js +304 -0
- package/dist/node_modules/@boombot/core/workflow/index.d.ts +3 -0
- package/dist/node_modules/@boombot/core/workflow/index.js +3 -0
- package/dist/node_modules/@boombot/core/workflow/types.d.ts +98 -0
- package/dist/node_modules/@boombot/core/workflow/types.js +21 -0
- package/dist/node_modules/@boombot/cronjobs/handlers.d.ts +11 -0
- package/dist/node_modules/@boombot/cronjobs/handlers.js +174 -0
- package/dist/node_modules/@boombot/cronjobs/index.d.ts +2 -0
- package/dist/node_modules/@boombot/cronjobs/index.js +2 -0
- package/dist/node_modules/@boombot/cronjobs/package.json +9 -0
- package/dist/node_modules/@boombot/cronjobs/service.d.ts +53 -0
- package/dist/node_modules/@boombot/cronjobs/service.js +200 -0
- package/dist/node_modules/@boombot/plugins/index.d.ts +2 -0
- package/dist/node_modules/@boombot/plugins/index.js +2 -0
- package/dist/node_modules/@boombot/plugins/installer.d.ts +45 -0
- package/dist/node_modules/@boombot/plugins/installer.js +487 -0
- package/dist/node_modules/@boombot/plugins/manager.d.ts +23 -0
- package/dist/node_modules/@boombot/plugins/manager.js +243 -0
- package/dist/node_modules/@boombot/plugins/package.json +9 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.d.ts +125 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.js +76 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.d.ts +220 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.js +60 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.d.ts +33 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.js +25 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.d.ts +4349 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.js +563 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.d.ts +32 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.js +61 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.d.ts +13 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.js +16 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/events.d.ts +567 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/events.js +395 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/index.d.ts +20 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/index.js +13 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/types.d.ts +91 -0
- package/dist/node_modules/@boombot/protocol/gateway-protocol/types.js +7 -0
- package/dist/node_modules/@boombot/protocol/index.d.ts +4 -0
- package/dist/node_modules/@boombot/protocol/index.js +3 -0
- package/dist/node_modules/@boombot/protocol/package.json +9 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.d.ts +41 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.js +17 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/index.d.ts +10 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/index.js +10 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.d.ts +58 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.js +116 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.d.ts +25 -0
- package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.js +1 -0
- package/dist/node_modules/@boombot/protocol/providers/cipher.d.ts +7 -0
- package/dist/node_modules/@boombot/protocol/providers/cipher.js +52 -0
- package/dist/node_modules/@boombot/protocol/providers/index.d.ts +19 -0
- package/dist/node_modules/@boombot/protocol/providers/index.js +19 -0
- package/dist/node_modules/@boombot/protocol/providers/key-roulette.d.ts +79 -0
- package/dist/node_modules/@boombot/protocol/providers/key-roulette.js +81 -0
- package/dist/node_modules/@boombot/protocol/providers/probe.d.ts +29 -0
- package/dist/node_modules/@boombot/protocol/providers/probe.js +96 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.d.ts +11 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.js +11 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/custom.d.ts +22 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/custom.js +222 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.d.ts +7 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.js +9 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/google.d.ts +10 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/google.js +10 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/index.d.ts +31 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/index.js +56 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/local.d.ts +10 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/local.js +11 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.d.ts +7 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.js +9 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.d.ts +10 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.js +10 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/openai.d.ts +7 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/openai.js +11 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/types.d.ts +58 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/types.js +1 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/xai.d.ts +7 -0
- package/dist/node_modules/@boombot/protocol/providers/profiles/xai.js +10 -0
- package/dist/node_modules/@boombot/protocol/providers/request-profile.d.ts +102 -0
- package/dist/node_modules/@boombot/protocol/providers/request-profile.js +118 -0
- package/dist/node_modules/@boombot/protocol/providers/service.d.ts +2 -0
- package/dist/node_modules/@boombot/protocol/providers/service.js +418 -0
- package/dist/node_modules/@boombot/protocol/providers/types.d.ts +141 -0
- package/dist/node_modules/@boombot/protocol/providers/types.js +16 -0
- package/dist/node_modules/@boombot/sandbox/fs-path.d.ts +13 -0
- package/dist/node_modules/@boombot/sandbox/fs-path.js +79 -0
- package/dist/node_modules/@boombot/sandbox/index.d.ts +13 -0
- package/dist/node_modules/@boombot/sandbox/index.js +13 -0
- package/dist/node_modules/@boombot/sandbox/native.d.ts +39 -0
- package/dist/node_modules/@boombot/sandbox/native.js +224 -0
- package/dist/node_modules/@boombot/sandbox/package.json +9 -0
- package/dist/node_modules/@boombot/sandbox/sandbox.d.ts +92 -0
- package/dist/node_modules/@boombot/sandbox/sandbox.js +229 -0
- package/dist/node_modules/@boombot/security/harness-guard/boundary.d.ts +22 -0
- package/dist/node_modules/@boombot/security/harness-guard/boundary.js +105 -0
- package/dist/node_modules/@boombot/security/harness-guard/gates.d.ts +90 -0
- package/dist/node_modules/@boombot/security/harness-guard/gates.js +791 -0
- package/dist/node_modules/@boombot/security/harness-guard/index.d.ts +23 -0
- package/dist/node_modules/@boombot/security/harness-guard/index.js +23 -0
- package/dist/node_modules/@boombot/security/harness-guard/policy.d.ts +20 -0
- package/dist/node_modules/@boombot/security/harness-guard/policy.js +70 -0
- package/dist/node_modules/@boombot/security/harness-guard/sanitizer.d.ts +53 -0
- package/dist/node_modules/@boombot/security/harness-guard/sanitizer.js +145 -0
- package/dist/node_modules/@boombot/security/harness-guard/types.d.ts +71 -0
- package/dist/node_modules/@boombot/security/harness-guard/types.js +10 -0
- package/dist/node_modules/@boombot/security/harness-guard/verifier.d.ts +59 -0
- package/dist/node_modules/@boombot/security/harness-guard/verifier.js +169 -0
- package/dist/node_modules/@boombot/security/index.d.ts +5 -0
- package/dist/node_modules/@boombot/security/index.js +9 -0
- package/dist/node_modules/@boombot/security/package.json +9 -0
- package/dist/node_modules/@boombot/security/policy/approval.d.ts +117 -0
- package/dist/node_modules/@boombot/security/policy/approval.js +223 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.d.ts +10 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.js +124 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.d.ts +25 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.js +70 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/gate.d.ts +38 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/gate.js +61 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.d.ts +12 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.js +234 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/index.d.ts +17 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/index.js +13 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/policy.d.ts +15 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/policy.js +39 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/types.d.ts +46 -0
- package/dist/node_modules/@boombot/security/reasoning-guard/types.js +7 -0
- package/dist/node_modules/@boombot/security/security/approval.d.ts +63 -0
- package/dist/node_modules/@boombot/security/security/approval.js +140 -0
- package/dist/node_modules/@boombot/security/security/audit.d.ts +39 -0
- package/dist/node_modules/@boombot/security/security/audit.js +70 -0
- package/dist/node_modules/@boombot/security/security/index.d.ts +12 -0
- package/dist/node_modules/@boombot/security/security/index.js +12 -0
- package/dist/node_modules/@boombot/security/security/trust.d.ts +79 -0
- package/dist/node_modules/@boombot/security/security/trust.js +87 -0
- package/dist/package.json +5 -0
- package/dist/proto/agent_core.proto +56 -0
- package/dist/python/agent-core-python/pyproject.toml +40 -0
- package/dist/python/agent-core-python/src/boombot_agent/__init__.py +5 -0
- package/dist/python/agent-core-python/src/boombot_agent/generated/__init__.py +0 -0
- package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2.py +54 -0
- package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2_grpc.py +140 -0
- package/dist/python/agent-core-python/src/boombot_agent/rpc.py +265 -0
- package/dist/python/agent-core-python/src/boombot_agent/turn.py +577 -0
- package/dist/python/agent-core-python/src/boombot_ml/__init__.py +12 -0
- package/dist/python/agent-core-python/src/boombot_ml/embeddings.py +58 -0
- package/dist/python/agent-core-python/src/boombot_ml/training.py +156 -0
- package/dist/python/agent-core-python/uv.lock +2856 -0
- package/dist/web/assets/ChatView-BZrSD-64.js +262 -0
- package/dist/web/assets/ChatView-Cahbjez6.css +1 -0
- package/dist/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/web/assets/MemoryView-BJbXqqs7.css +1 -0
- package/dist/web/assets/MemoryView-BfMq_6CD.js +1 -0
- package/dist/web/assets/SchedulesView-B22QmPR-.js +1 -0
- package/dist/web/assets/SchedulesView-C6XK7A8a.css +1 -0
- package/dist/web/assets/SessionsView-C1dqdhxI.css +1 -0
- package/dist/web/assets/SessionsView-DS0-aH2a.js +1 -0
- package/dist/web/assets/TasksView-Dtasg4hd.css +1 -0
- package/dist/web/assets/TasksView-ey0FLsW8.js +2 -0
- package/dist/web/assets/Textarea-DN3Zybl1.js +1 -0
- package/dist/web/assets/Tooltip-Bn2cqFPz.css +1 -0
- package/dist/web/assets/Tooltip-MzV2Gqnc.js +1 -0
- package/dist/web/assets/browser-Bnt73-Ub.js +8 -0
- package/dist/web/assets/index-BL8bi7Yt.css +1 -0
- package/dist/web/assets/index-CuPR73Tn.js +73 -0
- package/dist/web/favicon.svg +4 -0
- package/dist/web/index.html +26 -0
- package/dist/web/logo.jpg +0 -0
- package/dist/web/logo.png +0 -0
- 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
|
+
}
|