@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,511 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gateway memory service — wires `@boombot/core` (SQLite FTS5) into the
|
|
3
|
+
* gateway runtime.
|
|
4
|
+
*
|
|
5
|
+
* Two-tier retrieval (mirrors OpenClaw's active-memory escalation):
|
|
6
|
+
* - `recall` — LIGHT tier. Bounded FTS snapshot used by the agent turn loop
|
|
7
|
+
* before the first model round. Returns agent-core's `MemoryHit`
|
|
8
|
+
* (`{ id, content, score }`) so it plugs directly into `MemoryPort`.
|
|
9
|
+
* - `search` — DEEP tier. Larger result set with full snippets for the
|
|
10
|
+
* `memory.search` wire command. Returns the gateway protocol's `MemoryHit`
|
|
11
|
+
* (`{ id, excerpt, score }`).
|
|
12
|
+
*
|
|
13
|
+
* The two `MemoryHit` shapes differ (`content` vs `excerpt`); the
|
|
14
|
+
* adaptation happens here, inside the service, so callers on either side
|
|
15
|
+
* never see the other side's shape.
|
|
16
|
+
*
|
|
17
|
+
* Curation runs on its own timer (never inside the agent loop), uses the
|
|
18
|
+
* package's `TtlMemoryCurator`, and persists its run state in the store's
|
|
19
|
+
* audit trail under the sentinel id `memory:curation`. A failing curation
|
|
20
|
+
* run is logged and swallowed — it never breaks request handling.
|
|
21
|
+
*
|
|
22
|
+
* Consolidation (LLM extraction of durable facts from past conversations)
|
|
23
|
+
* runs on a second timer the same way, via `@boombot/core`'s
|
|
24
|
+
* `ConsolidationJob`. Its watermark cursor lives in the audit trail under
|
|
25
|
+
* the sentinel id `memory:consolidation`, mirroring the curation convention.
|
|
26
|
+
* Consolidation never runs inline after a turn — the turn loop stays hot
|
|
27
|
+
* and LLM spend stays bounded by the job's budget.
|
|
28
|
+
*
|
|
29
|
+
* Lifecycle: `startMemoryService(ctx)` attaches the service as
|
|
30
|
+
* `ctx.memoryService` and returns an async stop function that halts both
|
|
31
|
+
* timers and closes the database.
|
|
32
|
+
*/
|
|
33
|
+
import { randomUUID } from "node:crypto";
|
|
34
|
+
import { mkdirSync } from "node:fs";
|
|
35
|
+
import { dirname, join } from "node:path";
|
|
36
|
+
import { GLOBAL_SCOPE, conversationScope, CONSOLIDATION_STATE_ID, ConsolidationJob, DEFAULT_CONSOLIDATION_BUDGET, MAX_QUERY_CHARS, MAX_QUERY_TERMS, MemoryStore, principalScope, recallMemory, searchForPrincipal, SqliteFtsMemoryProvider, TtlMemoryCurator, InMemoryVectorIndex, reciprocalRankFusion, } from "@boombot/core";
|
|
37
|
+
export { CONSOLIDATION_STATE_ID };
|
|
38
|
+
/**
|
|
39
|
+
* Terms the FTS layer will actually index — mirrors `extractTerms`'s
|
|
40
|
+
* `TERM_PATTERN` (`packages/core/src/memory/search.ts`). Duplicated rather
|
|
41
|
+
* than imported because `extractTerms` is precisely what throws on an
|
|
42
|
+
* over-cap query, so calling it here to clamp would defeat the purpose.
|
|
43
|
+
*/
|
|
44
|
+
const QUERY_TERM_PATTERN = /[\p{L}\p{N}]+/gu;
|
|
45
|
+
/**
|
|
46
|
+
* Bound recall queries by characters and unique terms before calling FTS.
|
|
47
|
+
*
|
|
48
|
+
* Recall queries are whole user messages. The store's term cap exists to
|
|
49
|
+
* bound FTS work, but it was rejecting a turn's own context: any message over
|
|
50
|
+
* 32 terms made `extractTerms` throw `query exceeds 32 terms`, aborting the
|
|
51
|
+
* turn before the model ran. Clamping keeps recall working for long messages
|
|
52
|
+
* instead of silently dropping to zero hits. Repeated terms spend no extra budget.
|
|
53
|
+
*/
|
|
54
|
+
function clampRecallQuery(query) {
|
|
55
|
+
const terms = query.slice(0, MAX_QUERY_CHARS).match(QUERY_TERM_PATTERN) ?? [];
|
|
56
|
+
return [...new Set(terms.map((term) => term.toLowerCase()))].slice(0, MAX_QUERY_TERMS).join(" ");
|
|
57
|
+
}
|
|
58
|
+
const DEFAULT_RECALL_LIMIT = 5;
|
|
59
|
+
const DEFAULT_RECALL_CHARS_PER_HIT = 500;
|
|
60
|
+
const DEFAULT_RECALL_TOTAL_CHARS = 2500;
|
|
61
|
+
const DEFAULT_CURATION_INTERVAL_MS = 3_600_000; // 1h
|
|
62
|
+
const DEFAULT_CURATION_MAX_AGE_DAYS = 90;
|
|
63
|
+
const DEFAULT_CONSOLIDATION_INTERVAL_MS = 1_800_000; // 30min
|
|
64
|
+
/** Hard cap on raw extraction output accumulated from a streaming LLM. */
|
|
65
|
+
const MAX_CONSOLIDATION_RESPONSE_CHARS = 32_768;
|
|
66
|
+
/** Sentinel memory id under which curation run state is kept in the audit trail. */
|
|
67
|
+
export const CURATION_STATE_ID = "memory:curation";
|
|
68
|
+
function resolveOptions(options) {
|
|
69
|
+
const curationMaxAgeDays = options.curationMaxAgeDays ?? DEFAULT_CURATION_MAX_AGE_DAYS;
|
|
70
|
+
if (!Number.isFinite(curationMaxAgeDays) || curationMaxAgeDays < 1) {
|
|
71
|
+
throw new Error("MemoryService: curationMaxAgeDays must be >= 1");
|
|
72
|
+
}
|
|
73
|
+
const curationIntervalMs = options.curationIntervalMs ?? DEFAULT_CURATION_INTERVAL_MS;
|
|
74
|
+
if (!Number.isFinite(curationIntervalMs) || curationIntervalMs <= 0) {
|
|
75
|
+
throw new Error("MemoryService: curationIntervalMs must be > 0");
|
|
76
|
+
}
|
|
77
|
+
const consolidationIntervalMs = options.consolidationIntervalMs ?? DEFAULT_CONSOLIDATION_INTERVAL_MS;
|
|
78
|
+
if (!Number.isFinite(consolidationIntervalMs) || consolidationIntervalMs <= 0) {
|
|
79
|
+
throw new Error("MemoryService: consolidationIntervalMs must be > 0");
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
principalId: options.principalId ?? "local",
|
|
83
|
+
recallLimit: Math.min(Math.max(Math.floor(options.recallLimit ?? DEFAULT_RECALL_LIMIT), 1), 50),
|
|
84
|
+
curationIntervalMs,
|
|
85
|
+
curationMaxAgeDays,
|
|
86
|
+
curationDryRun: options.curationDryRun ?? false,
|
|
87
|
+
consolidationIntervalMs,
|
|
88
|
+
consolidationEnabled: options.consolidationEnabled ?? true,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Flatten a session's messages into the transcript the extractor sees.
|
|
93
|
+
* Only user + assistant turns are kept; system prompts and tool outputs
|
|
94
|
+
* are cut entirely (tool results can carry secrets and bloat the prompt).
|
|
95
|
+
*/
|
|
96
|
+
function flattenTranscript(messages) {
|
|
97
|
+
const lines = [];
|
|
98
|
+
for (const message of messages) {
|
|
99
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
100
|
+
continue;
|
|
101
|
+
const text = message.content.trim();
|
|
102
|
+
if (text === "")
|
|
103
|
+
continue;
|
|
104
|
+
lines.push(`${message.role}: ${text}`);
|
|
105
|
+
}
|
|
106
|
+
return lines.join("\n");
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Accumulate a streaming LLM completion into plain text for the extractor.
|
|
110
|
+
* Only `delta` is collected — `reasoningDelta` is deliberately ignored so
|
|
111
|
+
* chain-of-thought never lands in memory.
|
|
112
|
+
*/
|
|
113
|
+
async function collectLlmText(client, prompt) {
|
|
114
|
+
const message = { role: "user", content: prompt };
|
|
115
|
+
let text = "";
|
|
116
|
+
for await (const chunk of client.complete([message], [])) {
|
|
117
|
+
if (typeof chunk.delta === "string" && chunk.delta.length > 0) {
|
|
118
|
+
text += chunk.delta;
|
|
119
|
+
if (text.length >= MAX_CONSOLIDATION_RESPONSE_CHARS)
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return text.slice(0, MAX_CONSOLIDATION_RESPONSE_CHARS);
|
|
124
|
+
}
|
|
125
|
+
export class GatewayMemoryService {
|
|
126
|
+
store;
|
|
127
|
+
curationProvider;
|
|
128
|
+
curator = new TtlMemoryCurator();
|
|
129
|
+
consolidationProvider;
|
|
130
|
+
consolidationJob;
|
|
131
|
+
vectorIndex = new InMemoryVectorIndex();
|
|
132
|
+
resolveEmbedding;
|
|
133
|
+
principalId;
|
|
134
|
+
recallLimit;
|
|
135
|
+
curationIntervalMs;
|
|
136
|
+
curationMaxAgeDays;
|
|
137
|
+
curationDryRun;
|
|
138
|
+
log;
|
|
139
|
+
curationTimer;
|
|
140
|
+
curationRuns = 0;
|
|
141
|
+
lastCuration;
|
|
142
|
+
consolidationRuns = 0;
|
|
143
|
+
lastConsolidation;
|
|
144
|
+
constructor(dbPath, log, options = {}) {
|
|
145
|
+
const resolved = resolveOptions(options);
|
|
146
|
+
this.log = log;
|
|
147
|
+
this.principalId = resolved.principalId;
|
|
148
|
+
this.recallLimit = resolved.recallLimit;
|
|
149
|
+
this.curationIntervalMs = resolved.curationIntervalMs;
|
|
150
|
+
this.curationMaxAgeDays = resolved.curationMaxAgeDays;
|
|
151
|
+
this.curationDryRun = resolved.curationDryRun;
|
|
152
|
+
this.resolveEmbedding = options.resolveEmbedding;
|
|
153
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
154
|
+
this.store = MemoryStore.open(dbPath);
|
|
155
|
+
// Separate provider handle for the curator (its own connection; the
|
|
156
|
+
// curator only needs list/isPinned/archive and never touches recall).
|
|
157
|
+
this.curationProvider = new SqliteFtsMemoryProvider({
|
|
158
|
+
path: dbPath,
|
|
159
|
+
principalId: `${this.principalId}:curator`,
|
|
160
|
+
});
|
|
161
|
+
// Consolidation needs the session store (conversation source) and an LLM
|
|
162
|
+
// resolver. Without either it stays disabled — curation is unaffected.
|
|
163
|
+
// Like the curator, it gets its own provider handle, this time scoped to
|
|
164
|
+
// the real principal so dedupe search sees the principal's own facts.
|
|
165
|
+
if (resolved.consolidationEnabled &&
|
|
166
|
+
options.sessions !== undefined &&
|
|
167
|
+
options.resolveLlm !== undefined) {
|
|
168
|
+
const sessions = options.sessions;
|
|
169
|
+
const resolveLlm = options.resolveLlm;
|
|
170
|
+
const principalId = resolved.principalId;
|
|
171
|
+
this.consolidationProvider = new SqliteFtsMemoryProvider({
|
|
172
|
+
path: dbPath,
|
|
173
|
+
principalId,
|
|
174
|
+
});
|
|
175
|
+
const llm = {
|
|
176
|
+
completeText: async (prompt) => {
|
|
177
|
+
const client = await resolveLlm();
|
|
178
|
+
if (client === undefined) {
|
|
179
|
+
throw new Error("memory-consolidation: no LLM provider configured");
|
|
180
|
+
}
|
|
181
|
+
return collectLlmText(client, prompt);
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
this.consolidationJob = new ConsolidationJob({
|
|
185
|
+
llm,
|
|
186
|
+
store: this.consolidationProvider,
|
|
187
|
+
conversations: this.buildConversationSource(sessions, principalId),
|
|
188
|
+
watermarks: this.buildWatermarkStore(),
|
|
189
|
+
budget: DEFAULT_CONSOLIDATION_BUDGET,
|
|
190
|
+
intervalMs: resolved.consolidationIntervalMs,
|
|
191
|
+
onError: (error) => {
|
|
192
|
+
this.log.error("[memory] consolidation run failed; continuing", error);
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
this.consolidationProvider = undefined;
|
|
198
|
+
this.consolidationJob = undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async recall(query, opts) {
|
|
202
|
+
const principal = this.principalId;
|
|
203
|
+
const readableScopes = opts?.readableScopes ?? [
|
|
204
|
+
...(opts?.channel ? [] : [principalScope(principal)]),
|
|
205
|
+
GLOBAL_SCOPE,
|
|
206
|
+
...(opts?.sessionScope ? [opts.sessionScope] : []),
|
|
207
|
+
...(opts?.channel ? [opts.chatId
|
|
208
|
+
? conversationScope(opts.channel, opts.chatId)
|
|
209
|
+
: principalScope(`channel:${opts.channel}`)] : [])
|
|
210
|
+
];
|
|
211
|
+
const normalizedQuery = clampRecallQuery(query);
|
|
212
|
+
if (normalizedQuery === '')
|
|
213
|
+
return [];
|
|
214
|
+
const maxCharsPerHit = Number.parseInt(process.env['BOOMBOT_MEMORY_RECALL_CHARS_PER_HIT'] || '', 10) || DEFAULT_RECALL_CHARS_PER_HIT;
|
|
215
|
+
const maxTotalChars = Number.parseInt(process.env['BOOMBOT_MEMORY_RECALL_TOTAL_CHARS'] || '', 10) || DEFAULT_RECALL_TOTAL_CHARS;
|
|
216
|
+
const snapshot = recallMemory(this.store, {
|
|
217
|
+
authorization: { principalId: principal, readableScopes },
|
|
218
|
+
query: normalizedQuery,
|
|
219
|
+
maxResults: this.recallLimit,
|
|
220
|
+
maxCharsPerHit,
|
|
221
|
+
maxTotalChars,
|
|
222
|
+
});
|
|
223
|
+
const lexicalHits = snapshot.hits.map((hit) => ({
|
|
224
|
+
id: hit.record.id,
|
|
225
|
+
score: hit.score,
|
|
226
|
+
item: {
|
|
227
|
+
id: hit.record.id,
|
|
228
|
+
content: hit.snippet,
|
|
229
|
+
score: hit.score,
|
|
230
|
+
},
|
|
231
|
+
}));
|
|
232
|
+
// Hybrid Vector RAG (Reciprocal Rank Fusion) when embedding provider and indexed vectors are active
|
|
233
|
+
if (this.resolveEmbedding && this.vectorIndex.size() > 0) {
|
|
234
|
+
try {
|
|
235
|
+
const client = await this.resolveEmbedding();
|
|
236
|
+
if (client) {
|
|
237
|
+
const vectors = await client.embed([normalizedQuery]);
|
|
238
|
+
const queryVec = vectors[0];
|
|
239
|
+
if (queryVec) {
|
|
240
|
+
const allowedScopeIds = readableScopes.map((s) => typeof s === 'object' && s !== null && 'kind' in s
|
|
241
|
+
? `${s.kind}:${s.id ?? ''}`
|
|
242
|
+
: String(s));
|
|
243
|
+
const vectorHits = this.vectorIndex.search(new Float32Array(queryVec), {
|
|
244
|
+
topK: this.recallLimit,
|
|
245
|
+
allowedScopeIds,
|
|
246
|
+
});
|
|
247
|
+
if (vectorHits.length > 0) {
|
|
248
|
+
const semanticHits = vectorHits.map((hit) => {
|
|
249
|
+
const snippet = hit.metadata?.['snippet'] ?? '';
|
|
250
|
+
return {
|
|
251
|
+
id: hit.id,
|
|
252
|
+
score: hit.similarity,
|
|
253
|
+
item: {
|
|
254
|
+
id: hit.id,
|
|
255
|
+
content: snippet,
|
|
256
|
+
score: hit.similarity,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
const fused = reciprocalRankFusion(lexicalHits, semanticHits, { limit: this.recallLimit });
|
|
261
|
+
return fused.map((res) => res.item);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
this.log.debug?.('[memory] vector recall fallback to lexical due to error', err);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Default: Adapt store SearchHit -> agent-core MemoryHit { id, content, score }.
|
|
271
|
+
return lexicalHits.map((h) => h.item);
|
|
272
|
+
}
|
|
273
|
+
async search(query, opts) {
|
|
274
|
+
const limit = Math.min(Math.max(Math.floor(opts?.limit ?? 20), 1), 100);
|
|
275
|
+
const hits = searchForPrincipal(this.store, this.principalId, { query, limit });
|
|
276
|
+
// Adapt store SearchHit -> protocol MemoryHit { id, excerpt, score }.
|
|
277
|
+
return hits.map((hit) => ({
|
|
278
|
+
id: hit.record.id,
|
|
279
|
+
excerpt: hit.snippet,
|
|
280
|
+
score: hit.score,
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
async note(text, meta, scope) {
|
|
284
|
+
const now = new Date().toISOString();
|
|
285
|
+
const record = this.store.create({
|
|
286
|
+
scope: scope ?? principalScope(this.principalId),
|
|
287
|
+
text,
|
|
288
|
+
provenance: {
|
|
289
|
+
source: "model",
|
|
290
|
+
reference: "memory.note",
|
|
291
|
+
actorId: this.principalId,
|
|
292
|
+
at: now,
|
|
293
|
+
},
|
|
294
|
+
actorId: this.principalId,
|
|
295
|
+
});
|
|
296
|
+
// The store schema has no metadata column: meta is preserved in the
|
|
297
|
+
// audit trail (never in recall content) until the schema grows one.
|
|
298
|
+
if (meta !== undefined && Object.keys(meta).length > 0) {
|
|
299
|
+
this.store.insertAudit(randomUUID(), record.id, "create", this.principalId, now, `meta:${JSON.stringify(meta).slice(0, 2000)}`);
|
|
300
|
+
}
|
|
301
|
+
// Pin policy (P0-3): pin ONLY when the caller explicitly asks
|
|
302
|
+
// (`meta.pinned === 'true'`) or when the record lives in the durable
|
|
303
|
+
// global scope. Everything else stays unpinned so the TTL curator can
|
|
304
|
+
// archive stale records — pin-by-default had made curation dead code.
|
|
305
|
+
// An explicit `pinned: 'false'` always wins, even on the global scope.
|
|
306
|
+
const pinnedExplicitly = meta?.pinned === 'true';
|
|
307
|
+
const pinnedByScope = meta?.pinned !== 'false' && record.scope.kind === 'global';
|
|
308
|
+
if (pinnedExplicitly || pinnedByScope) {
|
|
309
|
+
this.store.pin(record.id, record.scope);
|
|
310
|
+
}
|
|
311
|
+
// Index vector in background for Hybrid RAG semantic recall
|
|
312
|
+
if (this.resolveEmbedding) {
|
|
313
|
+
this.resolveEmbedding()
|
|
314
|
+
.then(async (client) => {
|
|
315
|
+
if (!client)
|
|
316
|
+
return;
|
|
317
|
+
const vectors = await client.embed([text]);
|
|
318
|
+
const vec = vectors[0];
|
|
319
|
+
if (vec) {
|
|
320
|
+
const scopeId = typeof record.scope === 'object' && record.scope !== null && 'kind' in record.scope
|
|
321
|
+
? `${record.scope.kind}:${record.scope.id ?? ''}`
|
|
322
|
+
: String(record.scope);
|
|
323
|
+
this.vectorIndex.upsert({
|
|
324
|
+
id: record.id,
|
|
325
|
+
scopeId,
|
|
326
|
+
vector: new Float32Array(vec),
|
|
327
|
+
metadata: { snippet: text.slice(0, DEFAULT_RECALL_CHARS_PER_HIT) },
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
})
|
|
331
|
+
.catch((err) => {
|
|
332
|
+
this.log.debug?.('[memory] vector indexing failed for note', err);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return { id: record.id };
|
|
336
|
+
}
|
|
337
|
+
/** Diagnostics for health checks / tests. Not part of the MemoryService contract. */
|
|
338
|
+
curationStatus() {
|
|
339
|
+
return { runs: this.curationRuns, lastRun: this.lastCuration };
|
|
340
|
+
}
|
|
341
|
+
/** Start the background curation timer. Idempotent. */
|
|
342
|
+
startCuration() {
|
|
343
|
+
if (this.curationTimer !== undefined)
|
|
344
|
+
return;
|
|
345
|
+
this.curationTimer = setInterval(() => {
|
|
346
|
+
this.runCurationOnce();
|
|
347
|
+
}, this.curationIntervalMs);
|
|
348
|
+
// Never hold the process open for curation.
|
|
349
|
+
if (typeof this.curationTimer.unref === "function")
|
|
350
|
+
this.curationTimer.unref();
|
|
351
|
+
}
|
|
352
|
+
/** Drive one curation run now (used by the timer and by tests). */
|
|
353
|
+
runCurationOnce() {
|
|
354
|
+
try {
|
|
355
|
+
const report = this.curator.curate(this.curationProvider, {
|
|
356
|
+
maxAgeDays: this.curationMaxAgeDays,
|
|
357
|
+
dryRun: this.curationDryRun,
|
|
358
|
+
scopes: [GLOBAL_SCOPE, principalScope(this.principalId)],
|
|
359
|
+
});
|
|
360
|
+
this.curationRuns += 1;
|
|
361
|
+
this.lastCuration = {
|
|
362
|
+
at: report.at,
|
|
363
|
+
scanned: report.scanned,
|
|
364
|
+
archived: report.archived.length,
|
|
365
|
+
};
|
|
366
|
+
// Persist job state in the store (audit trail, stable sentinel id).
|
|
367
|
+
this.store.insertAudit(randomUUID(), CURATION_STATE_ID, "reindex", `${this.principalId}:curator`, report.at, JSON.stringify({
|
|
368
|
+
scanned: report.scanned,
|
|
369
|
+
kept: report.kept,
|
|
370
|
+
archived: report.archived.length,
|
|
371
|
+
skipped: report.skipped,
|
|
372
|
+
dryRun: report.dryRun,
|
|
373
|
+
}).slice(0, 2000));
|
|
374
|
+
this.log.info(`[memory] curation run #${this.curationRuns}: scanned=${report.scanned} archived=${report.archived.length}${report.dryRun ? " (dry-run)" : ""}`);
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
// Curation must never break request handling — log and continue.
|
|
378
|
+
this.log.error("[memory] curation run failed; continuing", error);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/** Diagnostics for health checks / tests. Not part of the MemoryService contract. */
|
|
382
|
+
consolidationStatus() {
|
|
383
|
+
return { runs: this.consolidationRuns, lastRun: this.lastConsolidation };
|
|
384
|
+
}
|
|
385
|
+
/** Start the background consolidation timer. Idempotent; no-op when disabled. */
|
|
386
|
+
startConsolidation() {
|
|
387
|
+
this.consolidationJob?.start();
|
|
388
|
+
}
|
|
389
|
+
/** Drive one consolidation run now (used by the timer and by tests). */
|
|
390
|
+
async runConsolidationOnce() {
|
|
391
|
+
const job = this.consolidationJob;
|
|
392
|
+
if (job === undefined) {
|
|
393
|
+
this.log.warn("[memory] consolidation skipped: no session store or LLM resolver wired");
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
const report = await job.runOnce();
|
|
398
|
+
this.consolidationRuns += 1;
|
|
399
|
+
this.lastConsolidation = {
|
|
400
|
+
at: report.at,
|
|
401
|
+
processed: report.processed,
|
|
402
|
+
factsCreated: report.factsCreated,
|
|
403
|
+
stopReason: report.stopReason,
|
|
404
|
+
};
|
|
405
|
+
this.log.info(`[memory] consolidation run #${this.consolidationRuns}: processed=${report.processed} facts=${report.factsCreated} stop=${report.stopReason}`);
|
|
406
|
+
return report;
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
// Consolidation must never break request handling — log and continue.
|
|
410
|
+
this.log.error("[memory] consolidation run failed; continuing", error);
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Conversation source over the gateway session store: sessions updated
|
|
416
|
+
* after the watermark cursor, oldest first. Facts are written to the
|
|
417
|
+
* principal scope — durable facts are cross-session by definition.
|
|
418
|
+
*/
|
|
419
|
+
buildConversationSource(sessions, principalId) {
|
|
420
|
+
return {
|
|
421
|
+
listEndedAfter: async (watermark, limit) => {
|
|
422
|
+
const all = sessions.list();
|
|
423
|
+
const after = watermark === null ? all : all.filter((s) => s.updatedAt > watermark);
|
|
424
|
+
after.sort((a, b) => (a.updatedAt < b.updatedAt ? -1 : a.updatedAt > b.updatedAt ? 1 : 0));
|
|
425
|
+
return after
|
|
426
|
+
.slice(0, Math.max(0, Math.floor(limit)))
|
|
427
|
+
.map((session) => ({
|
|
428
|
+
id: session.id,
|
|
429
|
+
principalId,
|
|
430
|
+
scope: principalScope(principalId),
|
|
431
|
+
transcript: flattenTranscript(sessions.getMessages(session.id)),
|
|
432
|
+
endedAt: session.updatedAt,
|
|
433
|
+
}));
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Watermark store over the memory store's audit trail, mirroring the
|
|
439
|
+
* `memory:curation` convention: run state is an append-only entry under a
|
|
440
|
+
* sentinel id, never a separate KV table. The cursor is the maximum
|
|
441
|
+
* `cursor` value seen, so concurrent writers cannot move it backwards.
|
|
442
|
+
*/
|
|
443
|
+
buildWatermarkStore() {
|
|
444
|
+
const store = this.store;
|
|
445
|
+
const actorId = `${this.principalId}:consolidation`;
|
|
446
|
+
return {
|
|
447
|
+
get: (key) => {
|
|
448
|
+
let cursor = null;
|
|
449
|
+
for (const entry of store.auditFor(key)) {
|
|
450
|
+
let parsed;
|
|
451
|
+
try {
|
|
452
|
+
parsed = JSON.parse(entry.detail);
|
|
453
|
+
}
|
|
454
|
+
catch {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (parsed !== null && typeof parsed === "object") {
|
|
458
|
+
const candidate = parsed.cursor;
|
|
459
|
+
if (typeof candidate === "string" && (cursor === null || candidate > cursor)) {
|
|
460
|
+
cursor = candidate;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return cursor;
|
|
465
|
+
},
|
|
466
|
+
set: (key, value) => {
|
|
467
|
+
store.insertAudit(randomUUID(), key, "reindex", actorId, new Date().toISOString(), JSON.stringify({ cursor: value }).slice(0, 2000));
|
|
468
|
+
},
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
stop() {
|
|
472
|
+
if (this.curationTimer !== undefined) {
|
|
473
|
+
clearInterval(this.curationTimer);
|
|
474
|
+
this.curationTimer = undefined;
|
|
475
|
+
}
|
|
476
|
+
this.consolidationJob?.stop();
|
|
477
|
+
this.consolidationProvider?.close();
|
|
478
|
+
this.curationProvider.close();
|
|
479
|
+
this.store.close();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Start the memory service: open the FTS5 store at
|
|
484
|
+
* `${ctx.dataDir}/memory.sqlite`, attach it as `ctx.memoryService`, and
|
|
485
|
+
* start the background curation + consolidation timers.
|
|
486
|
+
*
|
|
487
|
+
* The context may additionally carry `sessions` and `resolveLlm` (see
|
|
488
|
+
* `MemoryServiceContext`); without them consolidation stays disabled while
|
|
489
|
+
* curation keeps working.
|
|
490
|
+
*
|
|
491
|
+
* Returns an async stop function that halts both timers and closes the store.
|
|
492
|
+
* Throws on startup failure (unreadable dataDir, corrupt DB) — the gateway
|
|
493
|
+
* must not boot with a half-wired memory service.
|
|
494
|
+
*/
|
|
495
|
+
export async function startMemoryService(ctx, options = {}) {
|
|
496
|
+
const dbPath = join(ctx.dataDir, "memory.sqlite");
|
|
497
|
+
const service = new GatewayMemoryService(dbPath, ctx.log, {
|
|
498
|
+
...options,
|
|
499
|
+
sessions: options.sessions ?? ctx.sessions,
|
|
500
|
+
resolveLlm: options.resolveLlm ?? ctx.resolveLlm,
|
|
501
|
+
resolveEmbedding: options.resolveEmbedding ?? ctx.resolveEmbedding,
|
|
502
|
+
});
|
|
503
|
+
service.startCuration();
|
|
504
|
+
service.startConsolidation();
|
|
505
|
+
ctx.memoryService = service;
|
|
506
|
+
ctx.log.info(`[memory] service started (db=${dbPath})`);
|
|
507
|
+
return async () => {
|
|
508
|
+
service.stop();
|
|
509
|
+
ctx.log.info("[memory] service stopped");
|
|
510
|
+
};
|
|
511
|
+
}
|