@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,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @boombot/core — FTS5 full-text memory search for BoomBot.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - store: `MemoryStore` (SQLite + FTS5, trigger-synced index)
|
|
6
|
+
* - search: scoped, injection-safe full-text search with BM25 ranking
|
|
7
|
+
* - recall: bounded immutable snapshots for turns
|
|
8
|
+
* - lifecycle: revoke (tombstone) / forget (hard delete) with audit
|
|
9
|
+
* - indexer: batched rebuild + integrity verification
|
|
10
|
+
*/
|
|
11
|
+
export { MAX_TEXT_BYTES, MAX_QUERY_CHARS, MAX_QUERY_TERMS, MAX_SEARCH_LIMIT, MAX_SCOPE_ID_CHARS, MAX_SNIPPET_TOKENS, GLOBAL_SCOPE, type MemoryScopeKind, type MemoryScope, type MemoryProvenance, type MemoryRecord, type MemoryAuthorization, type MatchMode, type SearchOptions, type SearchHit, type RecallOptions, type MemorySnapshot, type RevokeInput, type ForgetInput, type MemoryAuditEntry, } from './types.js';
|
|
12
|
+
export { MemoryFtsError, type MemoryFtsErrorCode } from './errors.js';
|
|
13
|
+
export { MemoryStore, SCHEMA_VERSION, type CreateRecordInput, type RedactedMemoryRecord, } from './store.js';
|
|
14
|
+
export { search, searchForPrincipal, extractTerms, buildSafeMatchQuery, DEFAULT_HIGHLIGHT_START, DEFAULT_HIGHLIGHT_END, type PrincipalSearchOptions, } from './search.js';
|
|
15
|
+
export { recallMemory } from './recall.js';
|
|
16
|
+
export { revokeMemory, forgetMemory } from './lifecycle.js';
|
|
17
|
+
export { rebuildIndex, verifyIndex, type RebuildStats, type IndexHealth } from './indexer.js';
|
|
18
|
+
export { SqliteFtsMemoryProvider, principalScope, sessionScope, type MemoryProvider, type MemoryEntryInput, type ScoredHit, type SqliteFtsMemoryProviderOptions, } from './provider.js';
|
|
19
|
+
export { TtlMemoryCurator, CurationJob, type MemoryCurator, type CurationPolicy, type CurationReport, type CurationDecision, type CurationJobOptions, } from './curation.js';
|
|
20
|
+
export * from './vector-index.js';
|
|
21
|
+
export * from './hybrid-search.js';
|
|
22
|
+
export { ScopeResolver, conversationScope, groupScope, type ScopeContext, } from './scope-resolver.js';
|
|
23
|
+
export { CONSOLIDATION_STATE_ID, CONSOLIDATION_ACTOR_ID, ConsolidationJob, buildExtractionPrompt, parseExtractedFacts, runConsolidation, DEFAULT_CONSOLIDATION_BUDGET, ConsolidationBudgetTracker, type ConsolidationJobOptions, type ConsolidationLlm, type ConsolidationReport, type ConsolidationBudget, type ConversationSource, type EndedConversation, type RunConsolidationDeps, type WatermarkStore, type BudgetStopReason, type BudgetUsage, } from './consolidation/index.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @boombot/core — FTS5 full-text memory search for BoomBot.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - store: `MemoryStore` (SQLite + FTS5, trigger-synced index)
|
|
6
|
+
* - search: scoped, injection-safe full-text search with BM25 ranking
|
|
7
|
+
* - recall: bounded immutable snapshots for turns
|
|
8
|
+
* - lifecycle: revoke (tombstone) / forget (hard delete) with audit
|
|
9
|
+
* - indexer: batched rebuild + integrity verification
|
|
10
|
+
*/
|
|
11
|
+
export { MAX_TEXT_BYTES, MAX_QUERY_CHARS, MAX_QUERY_TERMS, MAX_SEARCH_LIMIT, MAX_SCOPE_ID_CHARS, MAX_SNIPPET_TOKENS, GLOBAL_SCOPE, } from './types.js';
|
|
12
|
+
export { MemoryFtsError } from './errors.js';
|
|
13
|
+
export { MemoryStore, SCHEMA_VERSION, } from './store.js';
|
|
14
|
+
export { search, searchForPrincipal, extractTerms, buildSafeMatchQuery, DEFAULT_HIGHLIGHT_START, DEFAULT_HIGHLIGHT_END, } from './search.js';
|
|
15
|
+
export { recallMemory } from './recall.js';
|
|
16
|
+
export { revokeMemory, forgetMemory } from './lifecycle.js';
|
|
17
|
+
export { rebuildIndex, verifyIndex } from './indexer.js';
|
|
18
|
+
export { SqliteFtsMemoryProvider, principalScope, sessionScope, } from './provider.js';
|
|
19
|
+
export { TtlMemoryCurator, CurationJob, } from './curation.js';
|
|
20
|
+
export * from './vector-index.js';
|
|
21
|
+
export * from './hybrid-search.js';
|
|
22
|
+
export { ScopeResolver, conversationScope, groupScope, } from './scope-resolver.js';
|
|
23
|
+
export { CONSOLIDATION_STATE_ID, CONSOLIDATION_ACTOR_ID, ConsolidationJob, buildExtractionPrompt, parseExtractedFacts, runConsolidation, DEFAULT_CONSOLIDATION_BUDGET, ConsolidationBudgetTracker, } from './consolidation/index.js';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { MemoryStore } from './store.js';
|
|
2
|
+
export interface RebuildStats {
|
|
3
|
+
indexed: number;
|
|
4
|
+
batches: number;
|
|
5
|
+
elapsedMs: number;
|
|
6
|
+
}
|
|
7
|
+
export interface IndexHealth {
|
|
8
|
+
liveRows: number;
|
|
9
|
+
indexedRows: number;
|
|
10
|
+
/** True when every live row is indexed and no dead row is indexed. */
|
|
11
|
+
ok: boolean;
|
|
12
|
+
/** Row ids present in the index but missing/dead in memory_records. */
|
|
13
|
+
orphaned: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Rebuild the FTS index from scratch in batches.
|
|
17
|
+
*
|
|
18
|
+
* SECURITY FIX (non-atomic rebuild, low): the old code ran
|
|
19
|
+
* `DELETE FROM memory_fts` up front, then re-inserted in batches — a
|
|
20
|
+
* concurrent reader querying mid-rebuild saw an EMPTY index (availability
|
|
21
|
+
* hole: searches silently returned nothing until the rebuild finished).
|
|
22
|
+
*
|
|
23
|
+
* The rebuild now happens in two phases:
|
|
24
|
+
* 1. SHADOW BUILD — live rows are indexed into `memory_fts_shadow` in
|
|
25
|
+
* batches, yielding to the event loop between batches. The live
|
|
26
|
+
* `memory_fts` table is untouched, so readers keep seeing the old
|
|
27
|
+
* (complete) index throughout.
|
|
28
|
+
* 2. ATOMIC MERGE — a single transaction merges the shadow into the live
|
|
29
|
+
* index and drops the shadow table. Readers see the old index, then
|
|
30
|
+
* the new one — never an empty one.
|
|
31
|
+
*
|
|
32
|
+
* Merge semantics (concurrent-write safety): `INSERT OR IGNORE` keeps rows
|
|
33
|
+
* the sync triggers wrote to the live index DURING the build — those are
|
|
34
|
+
* fresher than the shadow snapshot (e.g. a text update that landed
|
|
35
|
+
* mid-build). The `EXISTS (live row)` guard excludes rows tombstoned or
|
|
36
|
+
* hard-deleted during the build, so revocation is never resurrected by the
|
|
37
|
+
* merge.
|
|
38
|
+
*
|
|
39
|
+
* Residual note: a row whose INDEX TEXT was corrupt before the rebuild AND
|
|
40
|
+
* which is concurrently updated mid-build keeps the trigger-written (fresh)
|
|
41
|
+
* text — correct. A corrupt index entry for a row that is NOT touched during
|
|
42
|
+
* the build is repaired from the shadow — correct. There is no case where
|
|
43
|
+
* the merge makes the index worse than the pre-rebuild state.
|
|
44
|
+
*/
|
|
45
|
+
export declare function rebuildIndex(store: MemoryStore, batchSize?: number): Promise<RebuildStats>;
|
|
46
|
+
/** Compare live rows vs indexed rows; report orphans. */
|
|
47
|
+
export declare function verifyIndex(store: MemoryStore): IndexHealth;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index maintenance: batched rebuild and integrity verification.
|
|
3
|
+
*
|
|
4
|
+
* Normal writes stay in sync via SQLite triggers (see store.ts). Rebuild is
|
|
5
|
+
* for recovery paths the spec calls out: restart reconciliation, migration
|
|
6
|
+
* repair, and checksum-verified reindex tooling. Batches yield to the event
|
|
7
|
+
* loop between transactions so a large rebuild does not block the host.
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'node:crypto';
|
|
10
|
+
const DEFAULT_BATCH_SIZE = 500;
|
|
11
|
+
/** Yield control so a long rebuild never starves the event loop. */
|
|
12
|
+
function yieldToLoop() {
|
|
13
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Rebuild the FTS index from scratch in batches.
|
|
17
|
+
*
|
|
18
|
+
* SECURITY FIX (non-atomic rebuild, low): the old code ran
|
|
19
|
+
* `DELETE FROM memory_fts` up front, then re-inserted in batches — a
|
|
20
|
+
* concurrent reader querying mid-rebuild saw an EMPTY index (availability
|
|
21
|
+
* hole: searches silently returned nothing until the rebuild finished).
|
|
22
|
+
*
|
|
23
|
+
* The rebuild now happens in two phases:
|
|
24
|
+
* 1. SHADOW BUILD — live rows are indexed into `memory_fts_shadow` in
|
|
25
|
+
* batches, yielding to the event loop between batches. The live
|
|
26
|
+
* `memory_fts` table is untouched, so readers keep seeing the old
|
|
27
|
+
* (complete) index throughout.
|
|
28
|
+
* 2. ATOMIC MERGE — a single transaction merges the shadow into the live
|
|
29
|
+
* index and drops the shadow table. Readers see the old index, then
|
|
30
|
+
* the new one — never an empty one.
|
|
31
|
+
*
|
|
32
|
+
* Merge semantics (concurrent-write safety): `INSERT OR IGNORE` keeps rows
|
|
33
|
+
* the sync triggers wrote to the live index DURING the build — those are
|
|
34
|
+
* fresher than the shadow snapshot (e.g. a text update that landed
|
|
35
|
+
* mid-build). The `EXISTS (live row)` guard excludes rows tombstoned or
|
|
36
|
+
* hard-deleted during the build, so revocation is never resurrected by the
|
|
37
|
+
* merge.
|
|
38
|
+
*
|
|
39
|
+
* Residual note: a row whose INDEX TEXT was corrupt before the rebuild AND
|
|
40
|
+
* which is concurrently updated mid-build keeps the trigger-written (fresh)
|
|
41
|
+
* text — correct. A corrupt index entry for a row that is NOT touched during
|
|
42
|
+
* the build is repaired from the shadow — correct. There is no case where
|
|
43
|
+
* the merge makes the index worse than the pre-rebuild state.
|
|
44
|
+
*/
|
|
45
|
+
export async function rebuildIndex(store, batchSize = DEFAULT_BATCH_SIZE) {
|
|
46
|
+
const started = Date.now();
|
|
47
|
+
const db = store.raw();
|
|
48
|
+
let indexed = 0;
|
|
49
|
+
let batches = 0;
|
|
50
|
+
// Phase 1 — shadow build. A leftover shadow from a crashed rebuild is
|
|
51
|
+
// discarded first; the finally-cleanup below covers crashes mid-build.
|
|
52
|
+
db.exec('DROP TABLE IF EXISTS memory_fts_shadow');
|
|
53
|
+
db.exec(`CREATE VIRTUAL TABLE memory_fts_shadow USING fts5(
|
|
54
|
+
text,
|
|
55
|
+
memory_id UNINDEXED,
|
|
56
|
+
tokenize = 'unicode61'
|
|
57
|
+
)`);
|
|
58
|
+
try {
|
|
59
|
+
let lastRowid = 0;
|
|
60
|
+
for (;;) {
|
|
61
|
+
const rows = db
|
|
62
|
+
.prepare(`SELECT rowid AS rowid, text, id FROM memory_records
|
|
63
|
+
WHERE rowid > ? AND tombstoned_at IS NULL AND deleted_at IS NULL
|
|
64
|
+
ORDER BY rowid ASC LIMIT ?`)
|
|
65
|
+
.all(lastRowid, batchSize);
|
|
66
|
+
if (rows.length === 0)
|
|
67
|
+
break;
|
|
68
|
+
const insert = db.prepare(`INSERT INTO memory_fts_shadow (rowid, text, memory_id) VALUES (?, ?, ?)`);
|
|
69
|
+
db.exec('BEGIN IMMEDIATE');
|
|
70
|
+
try {
|
|
71
|
+
for (const row of rows)
|
|
72
|
+
insert.run(row.rowid, row.text, row.id);
|
|
73
|
+
db.exec('COMMIT');
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
db.exec('ROLLBACK');
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
indexed += rows.length;
|
|
80
|
+
batches += 1;
|
|
81
|
+
const lastRow = rows[rows.length - 1];
|
|
82
|
+
if (lastRow === undefined) {
|
|
83
|
+
throw new Error('indexer invariant violated: non-empty batch has no last row');
|
|
84
|
+
}
|
|
85
|
+
lastRowid = lastRow.rowid;
|
|
86
|
+
await yieldToLoop();
|
|
87
|
+
}
|
|
88
|
+
// Phase 2 — atomic merge into the live index.
|
|
89
|
+
db.exec('BEGIN IMMEDIATE');
|
|
90
|
+
try {
|
|
91
|
+
db.exec(`INSERT OR IGNORE INTO memory_fts (rowid, text, memory_id)
|
|
92
|
+
SELECT s.rowid, s.text, s.memory_id
|
|
93
|
+
FROM memory_fts_shadow AS s
|
|
94
|
+
WHERE EXISTS (
|
|
95
|
+
SELECT 1 FROM memory_records AS m
|
|
96
|
+
WHERE m.rowid = s.rowid
|
|
97
|
+
AND m.tombstoned_at IS NULL
|
|
98
|
+
AND m.deleted_at IS NULL
|
|
99
|
+
)`);
|
|
100
|
+
db.exec('DROP TABLE memory_fts_shadow');
|
|
101
|
+
db.exec('COMMIT');
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
try {
|
|
105
|
+
db.exec('ROLLBACK');
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// ignore rollback failure; the original error is what matters
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// Best-effort cleanup so a failed rebuild never leaves the shadow table
|
|
115
|
+
// (and its storage) behind.
|
|
116
|
+
try {
|
|
117
|
+
db.exec('DROP TABLE IF EXISTS memory_fts_shadow');
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// ignore
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
store.insertAudit(randomUUID(), '*', 'reindex', 'system', new Date().toISOString(), `indexed=${indexed}`);
|
|
125
|
+
return { indexed, batches, elapsedMs: Date.now() - started };
|
|
126
|
+
}
|
|
127
|
+
/** Compare live rows vs indexed rows; report orphans. */
|
|
128
|
+
export function verifyIndex(store) {
|
|
129
|
+
const db = store.raw();
|
|
130
|
+
const live = db.prepare(`SELECT COUNT(*) AS c FROM memory_records WHERE tombstoned_at IS NULL AND deleted_at IS NULL`).get().c;
|
|
131
|
+
const indexed = db.prepare(`SELECT COUNT(*) AS c FROM memory_fts`).get().c;
|
|
132
|
+
const orphaned = db
|
|
133
|
+
.prepare(`SELECT COUNT(*) AS c FROM memory_fts AS f
|
|
134
|
+
LEFT JOIN memory_records AS m ON m.rowid = f.rowid
|
|
135
|
+
WHERE m.rowid IS NULL OR m.tombstoned_at IS NOT NULL OR m.deleted_at IS NOT NULL`)
|
|
136
|
+
.get().c;
|
|
137
|
+
return { liveRows: live, indexedRows: indexed, ok: live === indexed && orphaned === 0, orphaned };
|
|
138
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type MemoryStore } from './store.js';
|
|
2
|
+
import type { ForgetInput, MemoryRecord, RevokeInput } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tombstone a record. Idempotent: revoking twice returns the record with the
|
|
5
|
+
* original tombstone timestamp and records an audit entry.
|
|
6
|
+
*/
|
|
7
|
+
export declare function revokeMemory(store: MemoryStore, input: RevokeInput): MemoryRecord;
|
|
8
|
+
/**
|
|
9
|
+
* Hard-delete a record. The FTS entry is purged by trigger; audit keeps
|
|
10
|
+
* metadata only (no content). Idempotent.
|
|
11
|
+
*/
|
|
12
|
+
export declare function forgetMemory(store: MemoryStore, input: ForgetInput): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record lifecycle: revocation (tombstone) and forget (hard delete).
|
|
3
|
+
*
|
|
4
|
+
* - Revoke: sets `tombstoned_at`. The sync trigger immediately drops the row
|
|
5
|
+
* from the FTS index, so the next search cannot return it, while the row
|
|
6
|
+
* itself survives as the audit trail (per spec: revocation is visible to
|
|
7
|
+
* authorized inspection, derived indexes are invalidated).
|
|
8
|
+
* - Forget: physically deletes the row (trigger purges the FTS entry). The
|
|
9
|
+
* audit log keeps action/actor/timestamp WITHOUT content.
|
|
10
|
+
*
|
|
11
|
+
* Both operations are idempotent and scope-checked: the caller must name the
|
|
12
|
+
* exact scope the record lives in, otherwise the operation fails — this
|
|
13
|
+
* prevents a principal from revoking another principal's records by id.
|
|
14
|
+
*/
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { forbiddenError, notFoundError } from './errors.js';
|
|
17
|
+
import { validateScope } from './store.js';
|
|
18
|
+
function loadInScope(store, id, scope) {
|
|
19
|
+
validateScope(scope);
|
|
20
|
+
const record = store.getForAudit(id, { forAudit: true });
|
|
21
|
+
if (record === undefined || record.scope.kind !== scope.kind || record.scope.id !== scope.id) {
|
|
22
|
+
// Same error whether the id is unknown or lives in another scope:
|
|
23
|
+
// existence must not leak across scope boundaries.
|
|
24
|
+
throw notFoundError(id);
|
|
25
|
+
}
|
|
26
|
+
return record;
|
|
27
|
+
}
|
|
28
|
+
function checkActor(actorId) {
|
|
29
|
+
if (typeof actorId !== 'string' || actorId.length === 0 || actorId.length > 256) {
|
|
30
|
+
throw forbiddenError('actorId is required');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Tombstone a record. Idempotent: revoking twice returns the record with the
|
|
35
|
+
* original tombstone timestamp and records an audit entry.
|
|
36
|
+
*/
|
|
37
|
+
export function revokeMemory(store, input) {
|
|
38
|
+
checkActor(input.actorId);
|
|
39
|
+
const record = loadInScope(store, input.id, input.scope);
|
|
40
|
+
const now = new Date().toISOString();
|
|
41
|
+
if (record.tombstonedAt === undefined) {
|
|
42
|
+
store.markTombstoned(input.id, now);
|
|
43
|
+
record.tombstonedAt = now;
|
|
44
|
+
}
|
|
45
|
+
store.insertAudit(randomUUID(), input.id, 'revoke', input.actorId, now, input.reason.slice(0, 500));
|
|
46
|
+
const refreshed = store.getForAudit(input.id, { forAudit: true });
|
|
47
|
+
if (refreshed === undefined)
|
|
48
|
+
throw notFoundError(input.id);
|
|
49
|
+
return refreshed;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Hard-delete a record. The FTS entry is purged by trigger; audit keeps
|
|
53
|
+
* metadata only (no content). Idempotent.
|
|
54
|
+
*/
|
|
55
|
+
export function forgetMemory(store, input) {
|
|
56
|
+
checkActor(input.actorId);
|
|
57
|
+
const record = store.getForAudit(input.id, { forAudit: true });
|
|
58
|
+
if (record === undefined)
|
|
59
|
+
return; // idempotent: already gone
|
|
60
|
+
if (record.scope.kind !== input.scope.kind || record.scope.id !== input.scope.id) {
|
|
61
|
+
throw notFoundError(input.id);
|
|
62
|
+
}
|
|
63
|
+
const now = new Date().toISOString();
|
|
64
|
+
store.hardDelete(input.id);
|
|
65
|
+
store.insertAudit(randomUUID(), input.id, 'forget', input.actorId, now, input.reason.slice(0, 500));
|
|
66
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type MemoryProvenance, type MemoryRecord, type MemoryScope } from './types.js';
|
|
2
|
+
/** Input for `MemoryProvider.save` — the host supplies scope + content. */
|
|
3
|
+
export interface MemoryEntryInput {
|
|
4
|
+
id?: string;
|
|
5
|
+
scope: MemoryScope;
|
|
6
|
+
text: string;
|
|
7
|
+
provenance: Omit<MemoryProvenance, 'at'> & {
|
|
8
|
+
at?: string;
|
|
9
|
+
};
|
|
10
|
+
createdAt?: string;
|
|
11
|
+
}
|
|
12
|
+
/** A ranked search result. `score` is provider-specific (lower = better). */
|
|
13
|
+
export interface ScoredHit {
|
|
14
|
+
record: MemoryRecord;
|
|
15
|
+
/** Provider-specific relevance score. Lower = more relevant. */
|
|
16
|
+
score: number;
|
|
17
|
+
/** Excerpt with highlight markers around matched terms. */
|
|
18
|
+
snippet: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The memory storage port. Builtin (FTS) and external (vector/remote)
|
|
22
|
+
* implementations share this surface; callers never depend on SQLite.
|
|
23
|
+
*
|
|
24
|
+
* All methods are synchronous for the builtin provider. External providers
|
|
25
|
+
* that need I/O should wrap this interface with an async facade at the
|
|
26
|
+
* host layer rather than forcing async onto every caller.
|
|
27
|
+
*/
|
|
28
|
+
export interface MemoryProvider {
|
|
29
|
+
/** 'builtin' = shipped with BoomBot; 'external' = host-provided. */
|
|
30
|
+
readonly kind: 'builtin' | 'external';
|
|
31
|
+
/** Persist a memory entry. Returns the stored record. */
|
|
32
|
+
save(entry: MemoryEntryInput): MemoryRecord;
|
|
33
|
+
/** Full-text / semantic search. Returns at most `limit` hits (default 20). */
|
|
34
|
+
search(query: string, limit?: number): ScoredHit[];
|
|
35
|
+
/** Hard-delete a record (audit keeps metadata only). Optional. */
|
|
36
|
+
delete?(id: string, scope: MemoryScope): void;
|
|
37
|
+
/** Tombstone a record: removed from search, kept for audit. Optional. */
|
|
38
|
+
archive?(id: string, scope: MemoryScope, reason?: string): void;
|
|
39
|
+
/** Protect a record from curation. Optional. */
|
|
40
|
+
pin?(id: string, scope: MemoryScope): void;
|
|
41
|
+
/** Remove curation protection. Optional. */
|
|
42
|
+
unpin?(id: string, scope: MemoryScope): void;
|
|
43
|
+
/** Whether a record is currently pinned. Optional. */
|
|
44
|
+
isPinned?(id: string, scope: MemoryScope): boolean;
|
|
45
|
+
/** List recent live records in a scope (newest first). Optional. */
|
|
46
|
+
list?(scope: MemoryScope, limit?: number): MemoryRecord[];
|
|
47
|
+
/** Release resources (close DB, flush buffers). Optional. */
|
|
48
|
+
close?(): void;
|
|
49
|
+
}
|
|
50
|
+
export interface SqliteFtsMemoryProviderOptions {
|
|
51
|
+
/** SQLite path, or ':memory:'. Default ':memory:'. */
|
|
52
|
+
path?: string;
|
|
53
|
+
/** Principal this provider serves. Never taken from user input. */
|
|
54
|
+
principalId: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builtin `MemoryProvider` backed by the ported SQLite FTS5 store
|
|
58
|
+
* (`MemoryStore`). Scoped search = the principal's own scope + the shared
|
|
59
|
+
* global scope; scope isolation and tombstone semantics are inherited
|
|
60
|
+
* unchanged from the tested store/search/lifecycle modules.
|
|
61
|
+
*/
|
|
62
|
+
export declare class SqliteFtsMemoryProvider implements MemoryProvider {
|
|
63
|
+
readonly kind: "builtin";
|
|
64
|
+
private readonly store;
|
|
65
|
+
private readonly principalId;
|
|
66
|
+
private closed;
|
|
67
|
+
constructor(options: SqliteFtsMemoryProviderOptions);
|
|
68
|
+
private assertOpen;
|
|
69
|
+
save(entry: MemoryEntryInput): MemoryRecord;
|
|
70
|
+
search(query: string, limit?: number): ScoredHit[];
|
|
71
|
+
delete(id: string, scope: MemoryScope): void;
|
|
72
|
+
archive(id: string, scope: MemoryScope, reason?: string): void;
|
|
73
|
+
pin(id: string, scope: MemoryScope): void;
|
|
74
|
+
unpin(id: string, scope: MemoryScope): void;
|
|
75
|
+
isPinned(id: string, scope: MemoryScope): boolean;
|
|
76
|
+
list(scope: MemoryScope, limit?: number): MemoryRecord[];
|
|
77
|
+
close(): void;
|
|
78
|
+
/** The shared global scope — visible to every principal. */
|
|
79
|
+
static globalScope(): MemoryScope;
|
|
80
|
+
}
|
|
81
|
+
/** Build a principal-private scope id. The id must come from auth, not input. */
|
|
82
|
+
export declare function principalScope(principalId: string): MemoryScope;
|
|
83
|
+
/** Build a session-private scope id. */
|
|
84
|
+
export declare function sessionScope(sessionId: string): MemoryScope;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @boombot/core — `MemoryProvider` abstraction.
|
|
3
|
+
*
|
|
4
|
+
* Lesson from Hermes/OpenClaw analysis (#6): the memory store must be an
|
|
5
|
+
* interface from day one so the builtin FTS implementation can be swapped
|
|
6
|
+
* for an external provider (vector DB, remote service) without touching the
|
|
7
|
+
* agent loop or the curator. Curation is deliberately NOT part of this
|
|
8
|
+
* interface — see `curation.ts`.
|
|
9
|
+
*/
|
|
10
|
+
import { forgetMemory, revokeMemory } from './lifecycle.js';
|
|
11
|
+
import { searchForPrincipal } from './search.js';
|
|
12
|
+
import { MemoryStore } from './store.js';
|
|
13
|
+
import { GLOBAL_SCOPE, } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Builtin `MemoryProvider` backed by the ported SQLite FTS5 store
|
|
16
|
+
* (`MemoryStore`). Scoped search = the principal's own scope + the shared
|
|
17
|
+
* global scope; scope isolation and tombstone semantics are inherited
|
|
18
|
+
* unchanged from the tested store/search/lifecycle modules.
|
|
19
|
+
*/
|
|
20
|
+
export class SqliteFtsMemoryProvider {
|
|
21
|
+
kind = 'builtin';
|
|
22
|
+
store;
|
|
23
|
+
principalId;
|
|
24
|
+
closed = false;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
if (typeof options.principalId !== 'string' || options.principalId.length === 0) {
|
|
27
|
+
throw new Error('SqliteFtsMemoryProvider: principalId is required');
|
|
28
|
+
}
|
|
29
|
+
this.principalId = options.principalId;
|
|
30
|
+
this.store = MemoryStore.open(options.path ?? ':memory:');
|
|
31
|
+
}
|
|
32
|
+
assertOpen() {
|
|
33
|
+
if (this.closed)
|
|
34
|
+
throw new Error('SqliteFtsMemoryProvider: provider is closed');
|
|
35
|
+
}
|
|
36
|
+
save(entry) {
|
|
37
|
+
this.assertOpen();
|
|
38
|
+
return this.store.create({
|
|
39
|
+
id: entry.id,
|
|
40
|
+
scope: entry.scope,
|
|
41
|
+
text: entry.text,
|
|
42
|
+
provenance: {
|
|
43
|
+
source: entry.provenance.source,
|
|
44
|
+
reference: entry.provenance.reference,
|
|
45
|
+
actorId: entry.provenance.actorId,
|
|
46
|
+
at: entry.provenance.at ?? new Date().toISOString(),
|
|
47
|
+
},
|
|
48
|
+
createdAt: entry.createdAt,
|
|
49
|
+
actorId: entry.provenance.actorId,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
search(query, limit = 20) {
|
|
53
|
+
this.assertOpen();
|
|
54
|
+
return searchForPrincipal(this.store, this.principalId, { query, limit }).map((hit) => ({
|
|
55
|
+
record: hit.record,
|
|
56
|
+
score: hit.score,
|
|
57
|
+
snippet: hit.snippet,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
delete(id, scope) {
|
|
61
|
+
this.assertOpen();
|
|
62
|
+
forgetMemory(this.store, { id, scope, actorId: this.principalId, reason: 'provider.delete' });
|
|
63
|
+
this.store.unpin(id, scope);
|
|
64
|
+
}
|
|
65
|
+
archive(id, scope, reason = 'curated') {
|
|
66
|
+
this.assertOpen();
|
|
67
|
+
revokeMemory(this.store, { id, scope, actorId: this.principalId, reason });
|
|
68
|
+
}
|
|
69
|
+
pin(id, scope) {
|
|
70
|
+
this.assertOpen();
|
|
71
|
+
this.store.pin(id, scope);
|
|
72
|
+
}
|
|
73
|
+
unpin(id, scope) {
|
|
74
|
+
this.assertOpen();
|
|
75
|
+
this.store.unpin(id, scope);
|
|
76
|
+
}
|
|
77
|
+
isPinned(id, scope) {
|
|
78
|
+
return this.store.isPinned(id, scope);
|
|
79
|
+
}
|
|
80
|
+
list(scope, limit = 100) {
|
|
81
|
+
this.assertOpen();
|
|
82
|
+
const rows = this.store
|
|
83
|
+
.raw()
|
|
84
|
+
.prepare(`SELECT id, scope_kind, scope_id, text, provenance_json, created_at
|
|
85
|
+
FROM memory_records
|
|
86
|
+
WHERE scope_kind = ? AND scope_id = ?
|
|
87
|
+
AND tombstoned_at IS NULL AND deleted_at IS NULL
|
|
88
|
+
ORDER BY created_at DESC, id ASC
|
|
89
|
+
LIMIT ?`)
|
|
90
|
+
.all(scope.kind, scope.id, limit);
|
|
91
|
+
return rows.map((row) => ({
|
|
92
|
+
id: row.id,
|
|
93
|
+
scope: { kind: row.scope_kind, id: row.scope_id },
|
|
94
|
+
text: row.text,
|
|
95
|
+
provenance: JSON.parse(row.provenance_json),
|
|
96
|
+
createdAt: row.created_at,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
close() {
|
|
100
|
+
if (!this.closed) {
|
|
101
|
+
this.closed = true;
|
|
102
|
+
this.store.close();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The shared global scope — visible to every principal. */
|
|
106
|
+
static globalScope() {
|
|
107
|
+
return GLOBAL_SCOPE;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Build a principal-private scope id. The id must come from auth, not input. */
|
|
111
|
+
export function principalScope(principalId) {
|
|
112
|
+
return { kind: 'principal', id: principalId };
|
|
113
|
+
}
|
|
114
|
+
/** Build a session-private scope id. */
|
|
115
|
+
export function sessionScope(sessionId) {
|
|
116
|
+
return { kind: 'session', id: sessionId };
|
|
117
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type MemoryStore } from './store.js';
|
|
2
|
+
import { type MemorySnapshot, type RecallOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Recall memory into an immutable, bounded snapshot.
|
|
5
|
+
* Without a query, returns the latest records per scope (created_at DESC).
|
|
6
|
+
*/
|
|
7
|
+
export declare function recallMemory(store: MemoryStore, options: RecallOptions): MemorySnapshot;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded recall — the BoomBot "bounded snapshot" philosophy.
|
|
3
|
+
*
|
|
4
|
+
* The agent runtime never holds the repository or a mutable memory object;
|
|
5
|
+
* the session owner converts authorized recall into an immutable, bounded
|
|
6
|
+
* snapshot before a turn. This module enforces the bounds:
|
|
7
|
+
* - maxResults: at most N records enter the snapshot;
|
|
8
|
+
* - maxCharsPerHit: each excerpt is truncated to a fixed width;
|
|
9
|
+
* - maxTotalChars: the whole snapshot stays within a byte/char budget.
|
|
10
|
+
*
|
|
11
|
+
* `truncated` tells the caller budget pressure existed, so the session owner
|
|
12
|
+
* can emit the degraded-but-visible diagnostic the spec requires instead of
|
|
13
|
+
* silently dropping context.
|
|
14
|
+
*/
|
|
15
|
+
import {} from 'node:sqlite';
|
|
16
|
+
import { validationError } from './errors.js';
|
|
17
|
+
import { search } from './search.js';
|
|
18
|
+
import { validateScope } from './store.js';
|
|
19
|
+
import {} from './types.js';
|
|
20
|
+
const DEFAULT_MAX_RESULTS = 10;
|
|
21
|
+
const DEFAULT_MAX_CHARS_PER_HIT = 500;
|
|
22
|
+
const DEFAULT_MAX_TOTAL_CHARS = 4000;
|
|
23
|
+
function truncateTo(text, maxChars) {
|
|
24
|
+
if (text.length <= maxChars)
|
|
25
|
+
return text;
|
|
26
|
+
return text.slice(0, Math.max(0, maxChars - 1)) + '…';
|
|
27
|
+
}
|
|
28
|
+
function authorizedScopes(auth) {
|
|
29
|
+
if (auth.readableScopes.length === 0) {
|
|
30
|
+
throw validationError('authorization carries no readable scopes');
|
|
31
|
+
}
|
|
32
|
+
for (const scope of auth.readableScopes)
|
|
33
|
+
validateScope(scope);
|
|
34
|
+
return auth.readableScopes;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Recall memory into an immutable, bounded snapshot.
|
|
38
|
+
* Without a query, returns the latest records per scope (created_at DESC).
|
|
39
|
+
*/
|
|
40
|
+
export function recallMemory(store, options) {
|
|
41
|
+
const scopes = authorizedScopes(options.authorization);
|
|
42
|
+
const maxResults = Math.min(Math.max(Math.floor(options.maxResults ?? DEFAULT_MAX_RESULTS), 1), 200);
|
|
43
|
+
const maxCharsPerHit = Math.min(Math.max(Math.floor(options.maxCharsPerHit ?? DEFAULT_MAX_CHARS_PER_HIT), 16), 8192);
|
|
44
|
+
const maxTotalChars = Math.min(Math.max(Math.floor(options.maxTotalChars ?? DEFAULT_MAX_TOTAL_CHARS), 64), 65536);
|
|
45
|
+
const evaluatedAt = new Date().toISOString();
|
|
46
|
+
let hits;
|
|
47
|
+
if (options.query !== undefined) {
|
|
48
|
+
// Over-fetch slightly so per-hit truncation still leaves maxResults.
|
|
49
|
+
hits = search(store, {
|
|
50
|
+
query: options.query,
|
|
51
|
+
scopes,
|
|
52
|
+
limit: maxResults,
|
|
53
|
+
match: options.match ?? 'any',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
hits = latestPerScope(store, scopes, maxResults);
|
|
58
|
+
}
|
|
59
|
+
const bounded = [];
|
|
60
|
+
let totalChars = 0;
|
|
61
|
+
let truncated = false;
|
|
62
|
+
for (const hit of hits) {
|
|
63
|
+
if (bounded.length >= maxResults) {
|
|
64
|
+
truncated = true;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
const excerpt = truncateTo(hit.snippet, maxCharsPerHit);
|
|
68
|
+
if (totalChars + excerpt.length > maxTotalChars) {
|
|
69
|
+
truncated = true;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
totalChars += excerpt.length;
|
|
73
|
+
bounded.push({ record: hit.record, score: hit.score, snippet: excerpt });
|
|
74
|
+
}
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
evaluatedAt,
|
|
77
|
+
hits: Object.freeze(bounded),
|
|
78
|
+
truncated,
|
|
79
|
+
totalChars,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Latest-first scoped listing for recall without a query. */
|
|
83
|
+
function latestPerScope(store, scopes, limit) {
|
|
84
|
+
const clauses = [];
|
|
85
|
+
const params = [];
|
|
86
|
+
for (const scope of scopes) {
|
|
87
|
+
clauses.push('(scope_kind = ? AND scope_id = ?)');
|
|
88
|
+
params.push(scope.kind, scope.id);
|
|
89
|
+
}
|
|
90
|
+
params.push(limit);
|
|
91
|
+
const rows = store
|
|
92
|
+
.raw()
|
|
93
|
+
.prepare(`SELECT id, scope_kind, scope_id, text, provenance_json, created_at
|
|
94
|
+
FROM memory_records
|
|
95
|
+
WHERE (${clauses.join(' OR ')})
|
|
96
|
+
AND tombstoned_at IS NULL AND deleted_at IS NULL
|
|
97
|
+
ORDER BY created_at DESC, id ASC
|
|
98
|
+
LIMIT ?`)
|
|
99
|
+
.all(...params);
|
|
100
|
+
return rows.map((row) => ({
|
|
101
|
+
record: {
|
|
102
|
+
id: row.id,
|
|
103
|
+
scope: { kind: row.scope_kind, id: row.scope_id },
|
|
104
|
+
text: row.text,
|
|
105
|
+
provenance: JSON.parse(row.provenance_json),
|
|
106
|
+
createdAt: row.created_at,
|
|
107
|
+
},
|
|
108
|
+
score: 0,
|
|
109
|
+
snippet: row.text,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type MemoryScope } from './types.js';
|
|
2
|
+
export interface ScopeContext {
|
|
3
|
+
readonly channel?: string;
|
|
4
|
+
readonly chatId?: string;
|
|
5
|
+
readonly senderId?: string;
|
|
6
|
+
readonly group?: string;
|
|
7
|
+
readonly isOperator?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function conversationScope(channel: string, chatId: string): MemoryScope;
|
|
10
|
+
export declare function groupScope(groupName: string): MemoryScope;
|
|
11
|
+
export declare class ScopeResolver {
|
|
12
|
+
/**
|
|
13
|
+
* Resolve scopes visible to this turn:
|
|
14
|
+
* - Global scope (public facts)
|
|
15
|
+
* - Principal scope (the local agent)
|
|
16
|
+
* - Sender scope (if user authenticated)
|
|
17
|
+
* - Group scope (if group assigned)
|
|
18
|
+
* - Conversation scope (channel + chatId)
|
|
19
|
+
*/
|
|
20
|
+
resolveReadableScopes(ctx: ScopeContext, principalId: string): readonly MemoryScope[];
|
|
21
|
+
/**
|
|
22
|
+
* Determine target scope for writing a new memory note.
|
|
23
|
+
* Default rule: narrowest scope first (conversation > group > sender > channel).
|
|
24
|
+
* Global scope is strictly reserved for operators.
|
|
25
|
+
*/
|
|
26
|
+
resolveWritableScope(ctx: ScopeContext, requestedScope?: MemoryScope): MemoryScope;
|
|
27
|
+
}
|