@vellumai/assistant 0.3.5 → 0.3.6
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 +51 -0
- package/eslint.config.mjs +31 -0
- package/package.json +1 -1
- package/scripts/ipc/check-swift-decoder-drift.ts +4 -1
- package/scripts/ipc/generate-swift.ts +18 -2
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +338 -1
- package/src/__tests__/approval-conversation-turn.test.ts +214 -0
- package/src/__tests__/browser-manager.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +130 -0
- package/src/__tests__/call-orchestrator.test.ts +752 -271
- package/src/__tests__/call-pointer-messages.test.ts +148 -0
- package/src/__tests__/call-recovery.test.ts +3 -0
- package/src/__tests__/call-routes-http.test.ts +5 -0
- package/src/__tests__/call-store.test.ts +3 -0
- package/src/__tests__/channel-approval-routes.test.ts +1260 -85
- package/src/__tests__/channel-approval.test.ts +37 -0
- package/src/__tests__/channel-approvals.test.ts +4 -65
- package/src/__tests__/channel-guardian.test.ts +556 -0
- package/src/__tests__/channel-readiness-service.test.ts +74 -7
- package/src/__tests__/checker.test.ts +14 -7
- package/src/__tests__/clarification-resolver.test.ts +44 -24
- package/src/__tests__/commit-message-enrichment-service.test.ts +9 -4
- package/src/__tests__/computer-use-session-working-dir.test.ts +8 -0
- package/src/__tests__/config-schema.test.ts +12 -7
- package/src/__tests__/context-window-manager.test.ts +30 -2
- package/src/__tests__/contradiction-checker.test.ts +20 -5
- package/src/__tests__/credential-security-invariants.test.ts +6 -2
- package/src/__tests__/db-migration-rollback.test.ts +752 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -0
- package/src/__tests__/fuzzy-match-property.test.ts +5 -5
- package/src/__tests__/guardian-action-store.test.ts +123 -0
- package/src/__tests__/guardian-action-sweep.test.ts +277 -0
- package/src/__tests__/guardian-dispatch.test.ts +389 -0
- package/src/__tests__/guardian-question-copy.test.ts +47 -0
- package/src/__tests__/handlers-telegram-config.test.ts +4 -2
- package/src/__tests__/handlers-twilio-config.test.ts +126 -0
- package/src/__tests__/intent-routing.test.ts +2 -0
- package/src/__tests__/ipc-snapshot.test.ts +228 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +828 -0
- package/src/__tests__/model-intents.test.ts +96 -0
- package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +42 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +130 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +89 -13
- package/src/__tests__/provider-error-scenarios.test.ts +621 -0
- package/src/__tests__/provider-fail-open-selection.test.ts +119 -0
- package/src/__tests__/qdrant-manager.test.ts +27 -20
- package/src/__tests__/relay-server.test.ts +779 -40
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +2 -0
- package/src/__tests__/run-orchestrator.test.ts +20 -4
- package/src/__tests__/runtime-runs-http.test.ts +17 -1
- package/src/__tests__/runtime-runs.test.ts +16 -0
- package/src/__tests__/schedule-store.test.ts +18 -4
- package/src/__tests__/scheduler-recurrence.test.ts +13 -4
- package/src/__tests__/session-abort-tool-results.test.ts +6 -0
- package/src/__tests__/session-agent-loop.test.ts +857 -0
- package/src/__tests__/session-conflict-gate.test.ts +6 -0
- package/src/__tests__/session-pre-run-repair.test.ts +6 -0
- package/src/__tests__/session-profile-injection.test.ts +6 -0
- package/src/__tests__/session-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/session-queue.test.ts +6 -0
- package/src/__tests__/session-runtime-assembly.test.ts +237 -13
- package/src/__tests__/session-slash-known.test.ts +6 -0
- package/src/__tests__/session-slash-queue.test.ts +6 -0
- package/src/__tests__/session-slash-unknown.test.ts +6 -0
- package/src/__tests__/session-surfaces-task-progress.test.ts +2 -0
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/session-workspace-injection.test.ts +6 -0
- package/src/__tests__/session-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/skills.test.ts +2 -0
- package/src/__tests__/sms-messaging-provider.test.ts +2 -1
- package/src/__tests__/starter-task-flow.test.ts +2 -0
- package/src/__tests__/swarm-dag-pathological.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +2 -0
- package/src/__tests__/task-management-tools.test.ts +2 -2
- package/src/__tests__/task-runner.test.ts +14 -4
- package/src/__tests__/terminal-tools.test.ts +25 -19
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +545 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +11 -11
- package/src/__tests__/tool-executor.test.ts +23 -24
- package/src/__tests__/trust-store.test.ts +3 -3
- package/src/__tests__/twilio-rest.test.ts +29 -0
- package/src/__tests__/twilio-routes-elevenlabs.test.ts +3 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +11 -0
- package/src/__tests__/twilio-routes.test.ts +141 -21
- package/src/__tests__/user-reference.test.ts +2 -0
- package/src/__tests__/voice-quality.test.ts +222 -0
- package/src/__tests__/web-search.test.ts +45 -29
- package/src/agent/loop.ts +1 -1
- package/src/agent-heartbeat/agent-heartbeat-service.ts +2 -10
- package/src/amazon/client.ts +1418 -0
- package/src/amazon/request-extractor.ts +135 -0
- package/src/amazon/session.ts +109 -0
- package/src/autonomy/autonomy-store.ts +5 -5
- package/src/browser-extension-relay/client.ts +124 -0
- package/src/browser-extension-relay/protocol.ts +63 -0
- package/src/browser-extension-relay/server.ts +177 -0
- package/src/bundler/app-bundler.ts +3 -3
- package/src/bundler/bundle-signer.ts +1 -1
- package/src/bundler/signature-verifier.ts +1 -1
- package/src/calls/call-conversation-messages.ts +33 -0
- package/src/calls/call-domain.ts +106 -5
- package/src/calls/call-orchestrator.ts +252 -54
- package/src/calls/call-pointer-messages.ts +53 -0
- package/src/calls/call-recovery.ts +3 -8
- package/src/calls/call-store.ts +69 -87
- package/src/calls/elevenlabs-config.ts +3 -2
- package/src/calls/guardian-action-sweep.ts +105 -0
- package/src/calls/guardian-dispatch.ts +203 -0
- package/src/calls/guardian-question-copy.ts +133 -0
- package/src/calls/relay-server.ts +466 -8
- package/src/calls/speaker-identification.ts +1 -1
- package/src/calls/twilio-config.ts +7 -5
- package/src/calls/twilio-provider.ts +6 -4
- package/src/calls/twilio-rest.ts +40 -15
- package/src/calls/twilio-routes.ts +60 -45
- package/src/calls/types.ts +3 -1
- package/src/channels/types.ts +25 -0
- package/src/cli/amazon.ts +815 -0
- package/src/cli/config-commands.ts +2 -2
- package/src/cli/core-commands.ts +4 -3
- package/src/cli/influencer.ts +244 -0
- package/src/cli/map.ts +89 -6
- package/src/cli.ts +1 -1
- package/src/config/agent-schema.ts +171 -0
- package/src/config/bundled-skills/amazon/SKILL.md +127 -0
- package/src/config/bundled-skills/amazon/icon.svg +13 -0
- package/src/config/bundled-skills/api-mapping/SKILL.md +78 -0
- package/src/config/bundled-skills/browser/SKILL.md +1 -0
- package/src/config/bundled-skills/browser/TOOLS.json +17 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +25 -0
- package/src/config/bundled-skills/doordash/SKILL.md +51 -51
- package/src/config/bundled-skills/email-setup/SKILL.md +14 -5
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +183 -0
- package/src/config/bundled-skills/influencer/SKILL.md +144 -0
- package/src/config/bundled-skills/macos-automation/icon.svg +12 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +72 -95
- package/src/config/bundled-skills/media-processing/TOOLS.json +57 -147
- package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +77 -0
- package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +69 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +303 -0
- package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +55 -0
- package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +86 -0
- package/src/config/bundled-skills/media-processing/services/gemini-map.ts +339 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +551 -0
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +7 -9
- package/src/config/bundled-skills/media-processing/services/reduce.ts +197 -0
- package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +88 -253
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +22 -153
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +28 -51
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +35 -270
- package/src/config/bundled-skills/messaging/SKILL.md +12 -2
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -7
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +2 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +86 -21
- package/src/config/bundled-skills/twitter/icon.svg +14 -0
- package/src/config/bundled-tool-registry.ts +310 -0
- package/src/config/calls-schema.ts +181 -0
- package/src/config/core-schema.ts +309 -0
- package/src/config/defaults.ts +26 -2
- package/src/config/env-registry.ts +162 -0
- package/src/config/env.ts +175 -0
- package/src/config/loader.ts +6 -6
- package/src/config/memory-schema.ts +528 -0
- package/src/config/sandbox-schema.ts +55 -0
- package/src/config/schema.ts +156 -1137
- package/src/config/skill-state.ts +1 -1
- package/src/config/skills-schema.ts +32 -0
- package/src/config/skills.ts +35 -24
- package/src/config/system-prompt.ts +107 -56
- package/src/config/templates/SOUL.md +1 -1
- package/src/config/types.ts +1 -0
- package/src/config/user-reference.ts +4 -9
- package/src/config/vellum-skills/catalog.json +0 -7
- package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +5 -1
- package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +1 -0
- package/src/config/vellum-skills/sms-setup/SKILL.md +112 -14
- package/src/context/window-manager.ts +27 -7
- package/src/daemon/approval-generators.ts +186 -0
- package/src/daemon/approved-devices-store.ts +140 -0
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/classifier.ts +35 -32
- package/src/daemon/config-watcher.ts +1 -1
- package/src/daemon/daemon-control.ts +217 -0
- package/src/daemon/handlers/apps.ts +2 -3
- package/src/daemon/handlers/config-channels.ts +158 -0
- package/src/daemon/handlers/config-inbox.ts +540 -0
- package/src/daemon/handlers/config-ingress.ts +231 -0
- package/src/daemon/handlers/config-integrations.ts +258 -0
- package/src/daemon/handlers/config-model.ts +143 -0
- package/src/daemon/handlers/config-parental.ts +163 -0
- package/src/daemon/handlers/config-scheduling.ts +172 -0
- package/src/daemon/handlers/config-slack.ts +92 -0
- package/src/daemon/handlers/config-telegram.ts +301 -0
- package/src/daemon/handlers/config-tools.ts +177 -0
- package/src/daemon/handlers/config-trust.ts +104 -0
- package/src/daemon/handlers/config-twilio.ts +1080 -0
- package/src/daemon/handlers/config.ts +53 -2463
- package/src/daemon/handlers/diagnostics.ts +1 -1
- package/src/daemon/handlers/dictation.ts +4 -6
- package/src/daemon/handlers/documents.ts +18 -32
- package/src/daemon/handlers/index.ts +9 -0
- package/src/daemon/handlers/misc.ts +3 -5
- package/src/daemon/handlers/pairing.ts +98 -0
- package/src/daemon/handlers/sessions.ts +54 -5
- package/src/daemon/handlers/shared.ts +3 -1
- package/src/daemon/handlers/skills.ts +1 -1
- package/src/daemon/handlers/twitter-auth.ts +2 -0
- package/src/daemon/handlers/work-items.ts +2 -2
- package/src/daemon/handlers/workspace-files.ts +4 -3
- package/src/daemon/install-cli-launchers.ts +113 -0
- package/src/daemon/ipc-contract/apps.ts +356 -0
- package/src/daemon/ipc-contract/browser.ts +74 -0
- package/src/daemon/ipc-contract/computer-use.ts +151 -0
- package/src/daemon/ipc-contract/diagnostics.ts +56 -0
- package/src/daemon/ipc-contract/documents.ts +74 -0
- package/src/daemon/ipc-contract/inbox.ts +209 -0
- package/src/daemon/ipc-contract/integrations.ts +284 -0
- package/src/daemon/ipc-contract/memory.ts +48 -0
- package/src/daemon/ipc-contract/messages.ts +211 -0
- package/src/daemon/ipc-contract/pairing.ts +45 -0
- package/src/daemon/ipc-contract/parental-control.ts +95 -0
- package/src/daemon/ipc-contract/schedules.ts +97 -0
- package/src/daemon/ipc-contract/sessions.ts +315 -0
- package/src/daemon/ipc-contract/shared.ts +42 -0
- package/src/daemon/ipc-contract/skills.ts +120 -0
- package/src/daemon/ipc-contract/subagents.ts +58 -0
- package/src/daemon/ipc-contract/surfaces.ts +250 -0
- package/src/daemon/ipc-contract/trust.ts +60 -0
- package/src/daemon/ipc-contract/work-items.ts +225 -0
- package/src/daemon/ipc-contract/workspace.ts +113 -0
- package/src/daemon/ipc-contract-inventory.json +60 -0
- package/src/daemon/ipc-contract-inventory.ts +55 -29
- package/src/daemon/ipc-contract.ts +226 -2527
- package/src/daemon/ipc-protocol.ts +1 -1
- package/src/daemon/ipc-validate.ts +7 -0
- package/src/daemon/lifecycle.ts +97 -379
- package/src/daemon/pairing-store.ts +177 -0
- package/src/daemon/providers-setup.ts +43 -0
- package/src/daemon/ride-shotgun-handler.ts +67 -2
- package/src/daemon/server.ts +60 -44
- package/src/daemon/session-agent-loop-handlers.ts +421 -0
- package/src/daemon/session-agent-loop.ts +113 -275
- package/src/daemon/session-dynamic-profile.ts +1 -1
- package/src/daemon/session-history.ts +1 -1
- package/src/daemon/session-media-retry.ts +1 -1
- package/src/daemon/session-messaging.ts +37 -2
- package/src/daemon/session-notifiers.ts +5 -25
- package/src/daemon/session-process.ts +99 -59
- package/src/daemon/session-queue-manager.ts +96 -4
- package/src/daemon/session-runtime-assembly.ts +149 -15
- package/src/daemon/session-surfaces.ts +19 -4
- package/src/daemon/session-tool-setup.ts +28 -30
- package/src/daemon/session-workspace.ts +1 -1
- package/src/daemon/session.ts +24 -1
- package/src/daemon/shutdown-handlers.ts +122 -0
- package/src/daemon/trace-emitter.ts +1 -1
- package/src/daemon/watch-handler.ts +36 -33
- package/src/doordash/cart-queries.ts +787 -0
- package/src/doordash/client.ts +144 -127
- package/src/doordash/order-queries.ts +85 -0
- package/src/doordash/queries.ts +10 -1308
- package/src/doordash/search-queries.ts +203 -0
- package/src/doordash/session.ts +3 -2
- package/src/doordash/store-queries.ts +246 -0
- package/src/doordash/types.ts +367 -0
- package/src/email/providers/agentmail.ts +2 -1
- package/src/email/providers/index.ts +3 -2
- package/src/email/service.ts +3 -2
- package/src/errors.ts +43 -0
- package/src/home-base/prebuilt/seed.ts +1 -1
- package/src/hooks/cli.ts +6 -5
- package/src/hooks/config.ts +6 -8
- package/src/hooks/discovery.ts +6 -5
- package/src/hooks/manager.ts +4 -3
- package/src/hooks/runner.ts +2 -2
- package/src/hooks/templates.ts +5 -5
- package/src/inbound/public-ingress-urls.ts +3 -1
- package/src/index.ts +4 -2
- package/src/influencer/client.ts +1104 -0
- package/src/instrument.ts +4 -3
- package/src/logfire.ts +4 -3
- package/src/memory/admin.ts +25 -35
- package/src/memory/attachments-store.ts +4 -7
- package/src/memory/channel-delivery-store.ts +30 -1
- package/src/memory/channel-guardian-store.ts +200 -1
- package/src/memory/clarification-resolver.ts +37 -33
- package/src/memory/conflict-store.ts +67 -61
- package/src/memory/contradiction-checker.ts +141 -117
- package/src/memory/conversation-store.ts +335 -51
- package/src/memory/db-connection.ts +27 -4
- package/src/memory/db-init.ts +121 -4
- package/src/memory/db.ts +14 -1
- package/src/memory/embedding-backend.ts +27 -5
- package/src/memory/embedding-ollama.ts +2 -1
- package/src/memory/entity-extractor.ts +38 -35
- package/src/memory/guardian-action-store.ts +430 -0
- package/src/memory/inbox-escalation-projection.ts +59 -0
- package/src/memory/inbox-thread-store.ts +218 -0
- package/src/memory/ingress-invite-store.ts +338 -0
- package/src/memory/ingress-member-store.ts +350 -0
- package/src/memory/items-extractor.ts +91 -97
- package/src/memory/job-handlers/index-maintenance.ts +3 -3
- package/src/memory/job-handlers/media-processing.ts +11 -42
- package/src/memory/job-handlers/summarization.ts +32 -26
- package/src/memory/job-utils.ts +3 -10
- package/src/memory/jobs-store.ts +6 -9
- package/src/memory/jobs-worker.ts +51 -36
- package/src/memory/migrations/001-job-deferrals.ts +45 -0
- package/src/memory/migrations/002-tool-invocations-fk.ts +43 -0
- package/src/memory/migrations/003-memory-fts-backfill.ts +24 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +87 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +80 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +62 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +254 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +208 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +83 -0
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +56 -0
- package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +63 -0
- package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +19 -0
- package/src/memory/migrations/013-guardian-action-tables.ts +68 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +76 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +27 -0
- package/src/memory/migrations/016-memory-segments-indexes.ts +11 -0
- package/src/memory/migrations/017-memory-items-indexes.ts +10 -0
- package/src/memory/migrations/018-remaining-table-indexes.ts +13 -0
- package/src/memory/migrations/index.ts +24 -0
- package/src/memory/migrations/registry.ts +79 -0
- package/src/memory/migrations/validate-migration-state.ts +69 -0
- package/src/memory/qdrant-manager.ts +49 -8
- package/src/memory/query-builder.ts +1 -1
- package/src/memory/raw-query.ts +119 -0
- package/src/memory/recall-cache.ts +4 -1
- package/src/memory/retriever.ts +160 -47
- package/src/memory/schema-migration.ts +25 -984
- package/src/memory/schema.ts +130 -7
- package/src/memory/search/entity.ts +10 -19
- package/src/memory/search/lexical.ts +81 -52
- package/src/memory/search/ranking.ts +21 -22
- package/src/memory/search/semantic.ts +157 -19
- package/src/memory/shared-app-links-store.ts +4 -5
- package/src/memory/validation.ts +19 -0
- package/src/messaging/draft-store.ts +5 -6
- package/src/messaging/providers/sms/adapter.ts +3 -6
- package/src/messaging/providers/telegram-bot/adapter.ts +2 -5
- package/src/messaging/providers/whatsapp/adapter.ts +136 -0
- package/src/messaging/providers/whatsapp/client.ts +67 -0
- package/src/messaging/style-analyzer.ts +5 -4
- package/src/messaging/thread-summarizer.ts +61 -69
- package/src/messaging/triage-engine.ts +62 -71
- package/src/migrations/config-merge.ts +53 -0
- package/src/migrations/data-layout.ts +68 -0
- package/src/migrations/data-merge.ts +33 -0
- package/src/migrations/hooks-merge.ts +90 -0
- package/src/migrations/index.ts +6 -0
- package/src/migrations/log.ts +23 -0
- package/src/migrations/skills-merge.ts +33 -0
- package/src/migrations/workspace-layout.ts +79 -0
- package/src/permissions/checker.ts +119 -11
- package/src/permissions/prompter.ts +14 -0
- package/src/permissions/shell-identity.ts +31 -1
- package/src/permissions/trust-store.ts +21 -1
- package/src/providers/anthropic/client.ts +4 -4
- package/src/providers/failover.ts +2 -2
- package/src/providers/model-intents.ts +70 -0
- package/src/providers/ollama/client.ts +2 -1
- package/src/providers/provider-send-message.ts +176 -0
- package/src/providers/registry.ts +71 -30
- package/src/providers/retry.ts +35 -1
- package/src/providers/types.ts +12 -1
- package/src/runtime/approval-conversation-turn.ts +97 -0
- package/src/runtime/approval-message-composer.ts +115 -5
- package/src/runtime/channel-approval-parser.ts +36 -2
- package/src/runtime/channel-approvals.ts +0 -21
- package/src/runtime/channel-guardian-service.ts +48 -7
- package/src/runtime/channel-readiness-service.ts +160 -34
- package/src/runtime/channel-readiness-types.ts +10 -4
- package/src/runtime/channel-retry-sweep.ts +184 -0
- package/src/runtime/guardian-context-resolver.ts +108 -0
- package/src/runtime/http-server.ts +275 -743
- package/src/runtime/http-types.ts +56 -3
- package/src/runtime/middleware/auth.ts +116 -0
- package/src/runtime/middleware/error-handler.ts +33 -0
- package/src/runtime/middleware/twilio-validation.ts +127 -0
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/call-routes.ts +49 -6
- package/src/runtime/routes/channel-delivery-routes.ts +170 -0
- package/src/runtime/routes/channel-guardian-routes.ts +1191 -0
- package/src/runtime/routes/channel-inbound-routes.ts +1152 -0
- package/src/runtime/routes/channel-route-shared.ts +144 -0
- package/src/runtime/routes/channel-routes.ts +32 -1634
- package/src/runtime/routes/conversation-routes.ts +50 -7
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +126 -0
- package/src/runtime/routes/pairing-routes.ts +143 -0
- package/src/runtime/routes/run-routes.ts +15 -1
- package/src/runtime/run-orchestrator.ts +52 -34
- package/src/schedule/schedule-store.ts +36 -32
- package/src/schedule/scheduler.ts +3 -3
- package/src/security/encrypted-store.ts +5 -7
- package/src/security/oauth2.ts +45 -15
- package/src/security/parental-control-store.ts +183 -0
- package/src/security/secret-allowlist.ts +4 -3
- package/src/security/secret-scanner.ts +5 -5
- package/src/security/secure-keys.ts +1 -1
- package/src/security/token-manager.ts +3 -2
- package/src/services/vercel-deploy.ts +6 -2
- package/src/skills/tool-manifest.ts +3 -3
- package/src/skills/vellum-catalog-remote.ts +75 -16
- package/src/slack/slack-webhook.ts +2 -1
- package/src/swarm/orchestrator.ts +92 -1
- package/src/swarm/router-planner.ts +6 -9
- package/src/swarm/worker-prompts.ts +9 -12
- package/src/tasks/task-compiler.ts +19 -28
- package/src/tasks/task-runner.ts +1 -1
- package/src/tools/assets/search.ts +15 -14
- package/src/tools/browser/__tests__/auth-detector.test.ts +1 -0
- package/src/tools/browser/auto-navigate.ts +1 -0
- package/src/tools/browser/browser-execution.ts +10 -1
- package/src/tools/browser/browser-manager.ts +119 -4
- package/src/tools/browser/network-recorder.ts +5 -0
- package/src/tools/credentials/broker.ts +11 -2
- package/src/tools/credentials/metadata-store.ts +18 -14
- package/src/tools/credentials/post-connect-hooks.ts +61 -0
- package/src/tools/credentials/vault.ts +49 -23
- package/src/tools/executor.ts +68 -9
- package/src/tools/host-terminal/cli-discover.ts +1 -1
- package/src/tools/network/script-proxy/http-forwarder.ts +1 -1
- package/src/tools/network/script-proxy/mitm-handler.ts +1 -1
- package/src/tools/network/script-proxy/server.ts +1 -1
- package/src/tools/network/script-proxy/session-manager.ts +6 -5
- package/src/tools/network/web-fetch.ts +18 -2
- package/src/tools/network/web-search.ts +7 -3
- package/src/tools/reminder/reminder-store.ts +14 -15
- package/src/tools/schedule/create.ts +1 -0
- package/src/tools/schedule/list.ts +2 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +5 -7
- package/src/tools/skills/skill-script-runner.ts +24 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -0
- package/src/tools/tasks/work-item-enqueue.ts +2 -2
- package/src/tools/terminal/evaluate-typescript.ts +21 -12
- package/src/tools/terminal/parser.ts +50 -0
- package/src/tools/watcher/delete.ts +6 -0
- package/src/tools/weather/service.ts +1 -1
- package/src/twitter/client.ts +190 -24
- package/src/twitter/session.ts +4 -3
- package/src/util/clipboard.ts +1 -1
- package/src/util/errors.ts +65 -8
- package/src/util/fs.ts +40 -0
- package/src/util/json.ts +10 -0
- package/src/util/log-redact.ts +189 -0
- package/src/util/logger.ts +19 -17
- package/src/util/object.ts +3 -0
- package/src/util/platform.ts +72 -365
- package/src/util/pricing.ts +1 -1
- package/src/util/promise-guard.ts +1 -1
- package/src/util/retry.ts +19 -0
- package/src/util/row-mapper.ts +79 -0
- package/src/util/silently.ts +21 -0
- package/src/watcher/engine.ts +5 -1
- package/src/watcher/provider-types.ts +20 -0
- package/src/watcher/providers/github.ts +156 -0
- package/src/watcher/providers/gmail.ts +1 -0
- package/src/watcher/providers/google-calendar.ts +1 -0
- package/src/watcher/providers/linear.ts +460 -0
- package/src/watcher/providers/slack.ts +1 -0
- package/src/work-items/work-item-runner.ts +1 -1
- package/src/workspace/git-service.ts +1 -1
- package/src/workspace/provider-commit-message-generator.ts +51 -22
- package/src/__tests__/call-bridge.test.ts +0 -517
- package/src/__tests__/session-process-bridge.test.ts +0 -244
- package/src/calls/call-bridge.ts +0 -168
- package/src/config/bundled-skills/media-processing/services/capability-registry.ts +0 -137
- package/src/config/bundled-skills/media-processing/services/event-detection-service.ts +0 -280
- package/src/config/bundled-skills/media-processing/services/feedback-aggregation.ts +0 -144
- package/src/config/bundled-skills/media-processing/services/feedback-store.ts +0 -136
- package/src/config/bundled-skills/media-processing/services/retrieval-service.ts +0 -95
- package/src/config/bundled-skills/media-processing/services/timeline-service.ts +0 -267
- package/src/config/bundled-skills/media-processing/tools/detect-events.ts +0 -110
- package/src/config/bundled-skills/media-processing/tools/recalibrate.ts +0 -235
- package/src/config/bundled-skills/media-processing/tools/select-tracking-profile.ts +0 -142
- package/src/config/bundled-skills/media-processing/tools/submit-feedback.ts +0 -150
- package/src/config/vellum-skills/google-oauth-setup/SKILL.md +0 -199
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface MigrationRegistryEntry {
|
|
2
|
+
/** The checkpoint key written to memory_checkpoints on completion. */
|
|
3
|
+
key: string;
|
|
4
|
+
/** Monotonic version number used for ordering assertions. */
|
|
5
|
+
version: number;
|
|
6
|
+
/** Keys of other migrations that must complete before this one runs. */
|
|
7
|
+
dependsOn?: string[];
|
|
8
|
+
/** Human-readable description for diagnostics and future authorship guidance. */
|
|
9
|
+
description: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Central registry of all checkpoint-based one-shot migrations. Each entry
|
|
14
|
+
// carries a monotonic version number (for documentation / ordering assertions)
|
|
15
|
+
// and an optional list of prerequisite checkpoint keys that must already be
|
|
16
|
+
// completed before this migration runs.
|
|
17
|
+
//
|
|
18
|
+
// Migrations that use pure DDL guards (CREATE TABLE IF NOT EXISTS, index
|
|
19
|
+
// presence checks, ALTER TABLE ADD COLUMN try/catch) are inherently idempotent
|
|
20
|
+
// and do not need entries here — they are safe to re-run on every startup.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
24
|
+
{
|
|
25
|
+
key: 'migration_job_deferrals',
|
|
26
|
+
version: 1,
|
|
27
|
+
description: 'Reconcile legacy deferral history from attempts column into deferrals column',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: 'migration_memory_entity_relations_dedup_v1',
|
|
31
|
+
version: 2,
|
|
32
|
+
description: 'Deduplicate entity relation edges before enforcing the (source, target, relation) unique index',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: 'migration_memory_items_fingerprint_scope_unique_v1',
|
|
36
|
+
version: 3,
|
|
37
|
+
description: 'Replace column-level UNIQUE on fingerprint with compound (fingerprint, scope_id) unique index',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'migration_memory_items_scope_salted_fingerprints_v1',
|
|
41
|
+
version: 4,
|
|
42
|
+
dependsOn: ['migration_memory_items_fingerprint_scope_unique_v1'],
|
|
43
|
+
description: 'Recompute memory item fingerprints to include scope_id prefix after schema change',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: 'migration_normalize_assistant_id_to_self_v1',
|
|
47
|
+
version: 5,
|
|
48
|
+
description: 'Normalize all assistant_id values in scoped tables to the implicit "self" single-tenant identity',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'migration_remove_assistant_id_columns_v1',
|
|
52
|
+
version: 6,
|
|
53
|
+
dependsOn: ['migration_normalize_assistant_id_to_self_v1'],
|
|
54
|
+
description: 'Rebuild four tables to drop the assistant_id column after normalization',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
key: 'migration_remove_assistant_id_lue_v1',
|
|
58
|
+
version: 7,
|
|
59
|
+
dependsOn: ['migration_normalize_assistant_id_to_self_v1'],
|
|
60
|
+
description: 'Remove assistant_id column from llm_usage_events (separate checkpoint from the four-table migration)',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
key: 'backfill_inbox_thread_state_from_bindings',
|
|
64
|
+
version: 8,
|
|
65
|
+
description: 'Seed assistant_inbox_thread_state from external_conversation_bindings',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: 'drop_active_search_index_v1',
|
|
69
|
+
version: 9,
|
|
70
|
+
description: 'Drop old idx_memory_items_active_search so it can be recreated with updated covering columns',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export interface MigrationValidationResult {
|
|
75
|
+
/** Keys of migrations whose checkpoint has value 'started' — started but never completed. */
|
|
76
|
+
crashed: string[];
|
|
77
|
+
/** Pairs where a completed migration's declared prerequisite is missing from checkpoints. */
|
|
78
|
+
dependencyViolations: Array<{ migration: string; missingDependency: string }>;
|
|
79
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { getSqliteFrom, type DrizzleDb } from '../db-connection.js';
|
|
2
|
+
import { getLogger } from '../../util/logger.js';
|
|
3
|
+
import { MIGRATION_REGISTRY, type MigrationValidationResult } from './registry.js';
|
|
4
|
+
|
|
5
|
+
const log = getLogger('memory-db');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Validate the applied migration state against the registry at startup.
|
|
9
|
+
*
|
|
10
|
+
* Logs warnings when a migration started but never completed (crash detected),
|
|
11
|
+
* and logs errors when a migration was applied but a declared prerequisite is
|
|
12
|
+
* missing from the checkpoints table (dependency ordering violation).
|
|
13
|
+
*
|
|
14
|
+
* Returns structured diagnostic data so callers (e.g. tests) can assert on the
|
|
15
|
+
* specific issues detected without having to re-query the DB or inspect logs.
|
|
16
|
+
*
|
|
17
|
+
* Call this AFTER all DDL and migration functions have run so that the final
|
|
18
|
+
* state is inspected.
|
|
19
|
+
*/
|
|
20
|
+
export function validateMigrationState(database: DrizzleDb): MigrationValidationResult {
|
|
21
|
+
const raw = getSqliteFrom(database);
|
|
22
|
+
|
|
23
|
+
let rows: Array<{ key: string; value: string }>;
|
|
24
|
+
try {
|
|
25
|
+
rows = raw.query(`SELECT key, value FROM memory_checkpoints`).all() as Array<{ key: string; value: string }>;
|
|
26
|
+
} catch {
|
|
27
|
+
// memory_checkpoints may not exist on a very old database; skip.
|
|
28
|
+
return { crashed: [], dependencyViolations: [] };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Detect crashed migrations: a checkpoint value of 'started' means the
|
|
32
|
+
// migration wrote its start marker but never reached the completion INSERT.
|
|
33
|
+
// The migration will re-run on the next startup (its own idempotency guard
|
|
34
|
+
// will determine safety), but we surface a warning for visibility.
|
|
35
|
+
const crashed = rows.filter((r) => r.value === 'started').map((r) => r.key);
|
|
36
|
+
if (crashed.length > 0) {
|
|
37
|
+
log.warn(
|
|
38
|
+
{ crashed },
|
|
39
|
+
'Crashed migrations detected — these migrations started but never completed; they will re-run on next startup',
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Only rows whose value is NOT 'started' represent truly completed migrations.
|
|
44
|
+
// In-progress/crashed checkpoints (value = 'started') must not count as applied
|
|
45
|
+
// dependencies — the migration never finished, so its postconditions are unmet.
|
|
46
|
+
const completed = new Set(rows.filter((r) => r.value !== 'started').map((r) => r.key));
|
|
47
|
+
|
|
48
|
+
const dependencyViolations: Array<{ migration: string; missingDependency: string }> = [];
|
|
49
|
+
|
|
50
|
+
// Validate dependency ordering.
|
|
51
|
+
for (const entry of MIGRATION_REGISTRY) {
|
|
52
|
+
if (!entry.dependsOn || entry.dependsOn.length === 0) continue;
|
|
53
|
+
// Only check entries that have been completed — unapplied or in-progress
|
|
54
|
+
// migrations have not had a chance to violate their prerequisites yet.
|
|
55
|
+
if (!completed.has(entry.key)) continue;
|
|
56
|
+
|
|
57
|
+
for (const dep of entry.dependsOn) {
|
|
58
|
+
if (!completed.has(dep)) {
|
|
59
|
+
log.error(
|
|
60
|
+
{ migration: entry.key, missingDependency: dep, version: entry.version },
|
|
61
|
+
'Migration dependency violation: this migration is marked complete but its declared prerequisite has no checkpoint — database schema may be inconsistent',
|
|
62
|
+
);
|
|
63
|
+
dependencyViolations.push({ migration: entry.key, missingDependency: dep });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { crashed, dependencyViolations };
|
|
69
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, chmodSync } from 'node:fs';
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { arch, platform } from 'node:os';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
4
5
|
import type { Subprocess } from 'bun';
|
|
5
6
|
import { getLogger } from '../util/logger.js';
|
|
6
7
|
import { getDataDir } from '../util/platform.js';
|
|
8
|
+
import { getQdrantUrlEnv } from '../config/env.js';
|
|
7
9
|
|
|
8
10
|
const log = getLogger('qdrant-manager');
|
|
9
11
|
|
|
@@ -15,6 +17,12 @@ const SHUTDOWN_GRACE_MS = 5_000;
|
|
|
15
17
|
export interface QdrantManagerConfig {
|
|
16
18
|
url: string;
|
|
17
19
|
storagePath?: string;
|
|
20
|
+
/** Override readyz poll interval (ms). Default: 200 */
|
|
21
|
+
readyzPollIntervalMs?: number;
|
|
22
|
+
/** Override readyz timeout (ms). Default: 30 000 */
|
|
23
|
+
readyzTimeoutMs?: number;
|
|
24
|
+
/** Override SIGTERM→SIGKILL grace period (ms). Default: 5 000 */
|
|
25
|
+
shutdownGraceMs?: number;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
/**
|
|
@@ -36,6 +44,9 @@ export class QdrantManager {
|
|
|
36
44
|
private readonly storagePath: string;
|
|
37
45
|
private readonly pidPath: string;
|
|
38
46
|
private readonly isExternal: boolean;
|
|
47
|
+
private readonly readyzPollIntervalMs: number;
|
|
48
|
+
private readonly readyzTimeoutMs: number;
|
|
49
|
+
private readonly shutdownGraceMs: number;
|
|
39
50
|
|
|
40
51
|
constructor(config: QdrantManagerConfig) {
|
|
41
52
|
this.url = config.url;
|
|
@@ -45,8 +56,12 @@ export class QdrantManager {
|
|
|
45
56
|
this.storagePath = config.storagePath ?? join(getDataDir(), 'qdrant');
|
|
46
57
|
this.pidPath = join(getDataDir(), 'qdrant', 'qdrant.pid');
|
|
47
58
|
|
|
59
|
+
this.readyzPollIntervalMs = config.readyzPollIntervalMs ?? READYZ_POLL_INTERVAL_MS;
|
|
60
|
+
this.readyzTimeoutMs = config.readyzTimeoutMs ?? READYZ_TIMEOUT_MS;
|
|
61
|
+
this.shutdownGraceMs = config.shutdownGraceMs ?? SHUTDOWN_GRACE_MS;
|
|
62
|
+
|
|
48
63
|
// External mode only if QDRANT_URL is explicitly set
|
|
49
|
-
this.isExternal = Boolean(
|
|
64
|
+
this.isExternal = Boolean(getQdrantUrlEnv());
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
async start(): Promise<void> {
|
|
@@ -107,7 +122,7 @@ export class QdrantManager {
|
|
|
107
122
|
// Wait for graceful shutdown
|
|
108
123
|
const graceful = await Promise.race([
|
|
109
124
|
this.process.exited.then(() => true),
|
|
110
|
-
new Promise<false>((resolve) => setTimeout(() => resolve(false),
|
|
125
|
+
new Promise<false>((resolve) => setTimeout(() => resolve(false), this.shutdownGraceMs)),
|
|
111
126
|
]);
|
|
112
127
|
|
|
113
128
|
if (!graceful) {
|
|
@@ -146,16 +161,42 @@ export class QdrantManager {
|
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
const filename = `qdrant-${target}.tar.gz`;
|
|
149
|
-
const
|
|
164
|
+
const baseUrl = `https://github.com/qdrant/qdrant/releases/download/v${QDRANT_VERSION}`;
|
|
165
|
+
const url = `${baseUrl}/${filename}`;
|
|
166
|
+
const checksumUrl = `${baseUrl}/${filename}.sha256`;
|
|
167
|
+
|
|
150
168
|
log.info({ url, binaryPath }, 'Downloading Qdrant binary');
|
|
151
169
|
|
|
152
|
-
|
|
170
|
+
// Fetch the tarball and its SHA-256 checksum in parallel
|
|
171
|
+
const [response, checksumResponse] = await Promise.all([
|
|
172
|
+
fetch(url),
|
|
173
|
+
fetch(checksumUrl),
|
|
174
|
+
]);
|
|
175
|
+
|
|
153
176
|
if (!response.ok) {
|
|
154
177
|
throw new Error(`Failed to download Qdrant: ${response.status} ${response.statusText} from ${url}`);
|
|
155
178
|
}
|
|
156
179
|
|
|
157
180
|
const tarball = await response.arrayBuffer();
|
|
158
181
|
|
|
182
|
+
// Verify SHA-256 integrity if the checksum file is available
|
|
183
|
+
if (checksumResponse.ok) {
|
|
184
|
+
const checksumText = (await checksumResponse.text()).trim();
|
|
185
|
+
// Checksum files contain "<hex> <filename>" or just "<hex>"
|
|
186
|
+
const expectedHash = checksumText.split(/\s+/)[0].toLowerCase();
|
|
187
|
+
const actualHash = createHash('sha256').update(Buffer.from(tarball)).digest('hex');
|
|
188
|
+
|
|
189
|
+
if (actualHash !== expectedHash) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`Qdrant binary checksum mismatch! ` +
|
|
192
|
+
`expected=${expectedHash} actual=${actualHash} url=${url}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
log.info({ hash: actualHash }, 'Qdrant binary checksum verified');
|
|
196
|
+
} else {
|
|
197
|
+
log.warn({ checksumUrl, status: checksumResponse.status }, 'Could not fetch Qdrant checksum — skipping integrity check');
|
|
198
|
+
}
|
|
199
|
+
|
|
159
200
|
// Extract the qdrant binary from the tarball
|
|
160
201
|
const binDir = dirname(binaryPath);
|
|
161
202
|
mkdirSync(binDir, { recursive: true });
|
|
@@ -185,16 +226,16 @@ export class QdrantManager {
|
|
|
185
226
|
|
|
186
227
|
private async waitForReady(): Promise<void> {
|
|
187
228
|
const start = Date.now();
|
|
188
|
-
while (Date.now() - start <
|
|
229
|
+
while (Date.now() - start < this.readyzTimeoutMs) {
|
|
189
230
|
try {
|
|
190
231
|
const res = await fetch(`${this.url}/readyz`);
|
|
191
232
|
if (res.ok) return;
|
|
192
233
|
} catch {
|
|
193
234
|
// Not ready yet
|
|
194
235
|
}
|
|
195
|
-
await Bun.sleep(
|
|
236
|
+
await Bun.sleep(this.readyzPollIntervalMs);
|
|
196
237
|
}
|
|
197
|
-
throw new Error(`Qdrant did not become ready within ${
|
|
238
|
+
throw new Error(`Qdrant did not become ready within ${this.readyzTimeoutMs}ms at ${this.url}`);
|
|
198
239
|
}
|
|
199
240
|
|
|
200
241
|
private getBinaryPath(): string {
|
|
@@ -203,7 +244,7 @@ export class QdrantManager {
|
|
|
203
244
|
|
|
204
245
|
private cleanupStaleProcess(): void {
|
|
205
246
|
const pid = this.readPid();
|
|
206
|
-
if (pid
|
|
247
|
+
if (pid == null) return;
|
|
207
248
|
|
|
208
249
|
try {
|
|
209
250
|
process.kill(pid, 0); // Check if process exists
|
|
@@ -23,7 +23,7 @@ export function buildMemoryQuery(
|
|
|
23
23
|
const requestText = clampSection(userRequest.trim(), maxUserRequestChars);
|
|
24
24
|
const sessionSummary = messages
|
|
25
25
|
.map((message) => getSummaryFromContextMessage(message))
|
|
26
|
-
.find((summary): summary is string => summary
|
|
26
|
+
.find((summary): summary is string => summary != null);
|
|
27
27
|
|
|
28
28
|
const content = requestText.length > 0 ? requestText : '(empty)';
|
|
29
29
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe wrappers for raw SQL queries against bun:sqlite.
|
|
3
|
+
*
|
|
4
|
+
* ## When to use raw SQL vs Drizzle ORM
|
|
5
|
+
*
|
|
6
|
+
* **Default to Drizzle** for all standard CRUD operations. Use raw SQL only when
|
|
7
|
+
* Drizzle cannot express the query or when a raw API is required:
|
|
8
|
+
*
|
|
9
|
+
* - **FTS5 operations**: MATCH operator, bm25() ranking, virtual table
|
|
10
|
+
* INSERT/DELETE. Drizzle has no FTS5 support.
|
|
11
|
+
*
|
|
12
|
+
* - **Schema migrations**: DDL statements (CREATE TABLE, ALTER TABLE, DROP TABLE),
|
|
13
|
+
* PRAGMA control, and transaction-wrapped table rebuilds. These are structural
|
|
14
|
+
* operations outside Drizzle's query-building scope.
|
|
15
|
+
*
|
|
16
|
+
* - **Affected-row checks after Drizzle .run()**: Drizzle's bun:sqlite adapter
|
|
17
|
+
* returns void from .run(), so checking changes() requires the raw client.
|
|
18
|
+
* Use `rawChanges()` for this.
|
|
19
|
+
*
|
|
20
|
+
* - **INSERT OR IGNORE / ON CONFLICT**: SQLite-specific upsert syntax that
|
|
21
|
+
* Drizzle's bun:sqlite adapter doesn't fully support.
|
|
22
|
+
*
|
|
23
|
+
* - **Atomic in-place updates**: Expressions like `SET count = count + 1` can
|
|
24
|
+
* use Drizzle's `sql` template, but raw SQL is acceptable when simpler.
|
|
25
|
+
*
|
|
26
|
+
* - **Bulk deletes across virtual tables**: Operations like clearing
|
|
27
|
+
* memory_segment_fts that reference virtual tables not modeled in Drizzle.
|
|
28
|
+
*
|
|
29
|
+
* For everything else — selects, inserts, updates, deletes, joins, aggregations,
|
|
30
|
+
* filtering, ordering, pagination — use Drizzle.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { Database, SQLQueryBindings } from 'bun:sqlite';
|
|
34
|
+
import { getSqlite, type DrizzleDb, getSqliteFrom } from './db-connection.js';
|
|
35
|
+
|
|
36
|
+
type SqlParam = SQLQueryBindings;
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Typed query helpers (global Drizzle instance)
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
/** Execute a raw SQL query and return a single typed row, or null if no match. */
|
|
43
|
+
export function rawGet<T>(sql: string, ...params: SqlParam[]): T | null {
|
|
44
|
+
return (getSqlite().query(sql).get(...params) as T) ?? null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Execute a raw SQL query and return all matching rows with type safety. */
|
|
48
|
+
export function rawAll<T>(sql: string, ...params: SqlParam[]): T[] {
|
|
49
|
+
return getSqlite().query(sql).all(...params) as T[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Execute a raw SQL statement (INSERT/UPDATE/DELETE) and return the number
|
|
54
|
+
* of affected rows.
|
|
55
|
+
*/
|
|
56
|
+
export function rawRun(sql: string, ...params: SqlParam[]): number {
|
|
57
|
+
getSqlite().query(sql).run(...params);
|
|
58
|
+
return rawChanges();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Execute batch SQL (multiple statements, no bindings). */
|
|
62
|
+
export function rawExec(sql: string): void {
|
|
63
|
+
getSqlite().exec(sql);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Return the number of rows affected by the most recent INSERT/UPDATE/DELETE.
|
|
68
|
+
*
|
|
69
|
+
* Useful after a Drizzle `.run()` call, since Drizzle's bun:sqlite adapter
|
|
70
|
+
* returns void and discards the changes count.
|
|
71
|
+
*/
|
|
72
|
+
export function rawChanges(): number {
|
|
73
|
+
return (getSqlite().query('SELECT changes() AS c').get() as { c: number }).c;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Typed query helpers (explicit Drizzle instance)
|
|
78
|
+
//
|
|
79
|
+
// Used by migrations and tests that receive the Drizzle instance as a
|
|
80
|
+
// parameter rather than using the global singleton.
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
/** Execute a raw SQL query against a specific Drizzle instance and return a single typed row. */
|
|
84
|
+
export function rawGetFrom<T>(db: DrizzleDb, sql: string, ...params: SqlParam[]): T | null {
|
|
85
|
+
return (getSqliteFrom(db).query(sql).get(...params) as T) ?? null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Execute a raw SQL query against a specific Drizzle instance and return all matching rows. */
|
|
89
|
+
export function rawAllFrom<T>(db: DrizzleDb, sql: string, ...params: SqlParam[]): T[] {
|
|
90
|
+
return getSqliteFrom(db).query(sql).all(...params) as T[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Execute a raw SQL statement against a specific Drizzle instance and return
|
|
95
|
+
* affected row count.
|
|
96
|
+
*/
|
|
97
|
+
export function rawRunFrom(db: DrizzleDb, sql: string, ...params: SqlParam[]): number {
|
|
98
|
+
const sqlite = getSqliteFrom(db);
|
|
99
|
+
sqlite.query(sql).run(...params);
|
|
100
|
+
return (sqlite.query('SELECT changes() AS c').get() as { c: number }).c;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Execute batch SQL against a specific Drizzle instance. */
|
|
104
|
+
export function rawExecFrom(db: DrizzleDb, sql: string): void {
|
|
105
|
+
getSqliteFrom(db).exec(sql);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create a prepared statement from the raw SQLite client.
|
|
110
|
+
* Useful when you need to execute the same parameterized query in a loop.
|
|
111
|
+
*/
|
|
112
|
+
export function rawPrepare(sql: string): ReturnType<Database['prepare']> {
|
|
113
|
+
return getSqlite().prepare(sql);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Create a prepared statement from a specific Drizzle instance. */
|
|
117
|
+
export function rawPrepareFrom(db: DrizzleDb, sql: string): ReturnType<Database['prepare']> {
|
|
118
|
+
return getSqliteFrom(db).prepare(sql);
|
|
119
|
+
}
|
|
@@ -68,11 +68,14 @@ export function getCachedRecall(
|
|
|
68
68
|
_cache.delete(key);
|
|
69
69
|
return undefined;
|
|
70
70
|
}
|
|
71
|
+
// Move to end of Map iteration order so it's treated as most-recently-used
|
|
72
|
+
_cache.delete(key);
|
|
73
|
+
_cache.set(key, entry);
|
|
71
74
|
return entry.result;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
/**
|
|
75
|
-
* Store a recall result in the cache. Evicts
|
|
78
|
+
* Store a recall result in the cache. Evicts least-recently-used entries when full.
|
|
76
79
|
*
|
|
77
80
|
* When `snapshotVersion` is provided, the entry is only stored if the
|
|
78
81
|
* snapshot still matches the current global version — this prevents a
|