@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022329.d89bf2f
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/ARCHITECTURE.md +94 -91
- package/Dockerfile +5 -16
- package/README.md +7 -10
- package/bun.lock +0 -4
- package/docs/architecture/security.md +20 -20
- package/docs/stt-provider-onboarding.md +4 -5
- package/docs/trusted-contact-access.md +7 -7
- package/eslint-rules/cli-no-daemon-internals.js +4 -0
- package/eslint.config.mjs +7 -1
- package/knip.json +0 -1
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +33 -0
- package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +39 -3
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
- package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
- package/openapi.yaml +1073 -225
- package/package.json +1 -4
- package/scripts/test.sh +35 -13
- package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
- package/src/__tests__/acp-session.test.ts +4 -1
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -6
- package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
- package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
- package/src/__tests__/app-source-watcher.test.ts +11 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +148 -3
- package/src/__tests__/assistant-attachments.test.ts +62 -4
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
- package/src/__tests__/attachments-store-heic-normalize.test.ts +230 -0
- package/src/__tests__/attachments-store.test.ts +3 -0
- package/src/__tests__/background-shell-bash.test.ts +34 -0
- package/src/__tests__/background-shell-host-bash.test.ts +12 -0
- package/src/__tests__/background-tool-registry.test.ts +97 -0
- package/src/__tests__/background-tool-routes.test.ts +72 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/btw-routes.test.ts +57 -3
- package/src/__tests__/call-controller.test.ts +474 -84
- package/src/__tests__/call-domain.test.ts +48 -1
- package/src/__tests__/call-pointer-messages.test.ts +57 -19
- package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +15 -14
- package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
- package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
- package/src/__tests__/call-setup-flow-verification.test.ts +925 -0
- package/src/__tests__/call-setup-flow.test.ts +311 -0
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +4 -7
- package/src/__tests__/channel-readiness-service.test.ts +0 -6
- package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
- package/src/__tests__/channel-retry-sweep.test.ts +76 -64
- package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
- package/src/__tests__/clear-all-lexical.test.ts +90 -0
- package/src/__tests__/compactor-media-strip.test.ts +177 -0
- package/src/__tests__/config-loader-backfill.test.ts +5 -5
- package/src/__tests__/config-schema.test.ts +17 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
- package/src/__tests__/contacts-relay-reads.test.ts +188 -23
- package/src/__tests__/contacts-tools.test.ts +42 -1
- package/src/__tests__/contacts-write.test.ts +181 -0
- package/src/__tests__/context-search-conversations-source.test.ts +220 -81
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +39 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -0
- package/src/__tests__/conversation-clear-safety.test.ts +0 -1
- package/src/__tests__/conversation-crud-enabled-plugins.test.ts +60 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -0
- package/src/__tests__/conversation-enabledplugins-route.test.ts +184 -0
- package/src/__tests__/conversation-error.test.ts +0 -18
- package/src/__tests__/conversation-fork-crud.test.ts +67 -0
- package/src/__tests__/conversation-history-web-search.test.ts +7 -137
- package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
- package/src/__tests__/conversation-process-callsite.test.ts +37 -0
- package/src/__tests__/conversation-queue.test.ts +149 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +392 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +84 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +407 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +36 -16
- package/src/__tests__/conversation-skill-tools.test.ts +73 -0
- package/src/__tests__/conversation-wipe.test.ts +20 -5
- package/src/__tests__/credential-prompt-route.test.ts +69 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -3
- package/src/__tests__/db-drop-messages-fts.test.ts +115 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -62
- package/src/__tests__/edit-propagation.test.ts +56 -2
- package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
- package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
- package/src/__tests__/guardian-question-mode.test.ts +57 -0
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/guardian-wait-controller.test.ts +619 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +33 -2
- package/src/__tests__/heic-fixture.ts +55 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
- package/src/__tests__/http-conversation-lineage.test.ts +6 -1
- package/src/__tests__/image-conversion.test.ts +170 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
- package/src/__tests__/introduction-card-resolver.test.ts +354 -0
- package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
- package/src/__tests__/invite-routes-http.test.ts +246 -420
- package/src/__tests__/job-handler-registration-guard.test.ts +104 -0
- package/src/__tests__/lexical-index-dual-write.test.ts +426 -0
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
- package/src/__tests__/list-messages-attachments.test.ts +159 -0
- package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
- package/src/__tests__/list-messages-queued.test.ts +25 -0
- package/src/__tests__/managed-store.test.ts +129 -1
- package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
- package/src/__tests__/media-stream-output.test.ts +350 -19
- package/src/__tests__/media-stream-server-integration.test.ts +943 -169
- package/src/__tests__/media-stream-stt-session.test.ts +498 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +19 -0
- package/src/__tests__/non-member-access-request.test.ts +349 -3
- package/src/__tests__/notification-decision-fallback.test.ts +104 -8
- package/src/__tests__/notification-decision-strategy.test.ts +57 -8
- package/src/__tests__/onboarding-template-contract.test.ts +27 -43
- package/src/__tests__/openai-provider.test.ts +33 -0
- package/src/__tests__/openai-responses-provider.test.ts +40 -0
- package/src/__tests__/persistence-layering-guard.test.ts +29 -20
- package/src/__tests__/persona-resolver.test.ts +56 -2
- package/src/__tests__/personal-memory-auth-bypass.test.ts +62 -0
- package/src/__tests__/phone.test.ts +1 -15
- package/src/__tests__/plugin-bootstrap.test.ts +25 -196
- package/src/__tests__/plugin-disabled-state.test.ts +33 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +227 -0
- package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +156 -42
- package/src/__tests__/plugin-injector-contribution.test.ts +4 -20
- package/src/__tests__/plugin-pipeline.test.ts +63 -1
- package/src/__tests__/plugin-route-contribution.test.ts +62 -115
- package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
- package/src/__tests__/plugin-types.test.ts +0 -1
- package/src/__tests__/pointer-conversation-trust.test.ts +38 -6
- package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
- package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
- package/src/__tests__/public-ingress-urls.test.ts +0 -48
- package/src/__tests__/qdrant-collection-migration.test.ts +145 -2
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
- package/src/__tests__/resolve-trust-class.test.ts +28 -10
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +137 -0
- package/src/__tests__/schedule-retry.test.ts +38 -14
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
- package/src/__tests__/schedule-routes.test.ts +14 -6
- package/src/__tests__/schedule-store.test.ts +3 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +17 -6
- package/src/__tests__/scheduler-recurrence.test.ts +57 -107
- package/src/__tests__/scheduler-reuse-conversation.test.ts +51 -46
- package/src/__tests__/scheduler-wake.test.ts +13 -23
- package/src/__tests__/scheduler-worker-standdown.test.ts +220 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
- package/src/__tests__/shell-observability.test.ts +1 -0
- package/src/__tests__/skill-boundary-guard.test.ts +3 -4
- package/src/__tests__/skill-load-plugin-scope.test.ts +238 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -0
- package/src/__tests__/skill-script-runner-host.test.ts +53 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
- package/src/__tests__/skill-tool-factory.test.ts +73 -1
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -14
- package/src/__tests__/slack-inbound-verification.test.ts +36 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +89 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
- package/src/__tests__/stt-hints.test.ts +2 -256
- package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +72 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
- package/src/__tests__/subagent-persistence.test.ts +122 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +1 -0
- package/src/__tests__/subagent-terminal-message.test.ts +99 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +78 -1
- package/src/__tests__/system-prompt.test.ts +17 -118
- package/src/__tests__/task-scheduler.test.ts +68 -89
- package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
- package/src/__tests__/telephony-tts-guard.test.ts +538 -0
- package/src/__tests__/title-generate-hook.test.ts +16 -0
- package/src/__tests__/tool-approval-handler.test.ts +87 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
- package/src/__tests__/tool-grant-request-escalation.test.ts +39 -0
- package/src/__tests__/trust-context-guards.test.ts +21 -10
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -0
- package/src/__tests__/twilio-provider.test.ts +17 -17
- package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
- package/src/__tests__/twilio-routes.test.ts +257 -387
- package/src/__tests__/twilio-validation.test.ts +1 -1
- package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
- package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
- package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
- package/src/__tests__/voice-quality.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -7
- package/src/__tests__/voice-session-bridge-processing-wait.test.ts +27 -0
- package/src/__tests__/voice-session-bridge.test.ts +1 -10
- package/src/__tests__/workspace-git-service.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
- package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
- package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +175 -0
- package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +118 -0
- package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +119 -0
- package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +191 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +235 -241
- package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
- package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
- package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
- package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
- package/src/acp/__tests__/session-manager.test.ts +6 -0
- package/src/acp/agent-process.test.ts +116 -0
- package/src/acp/agent-process.ts +71 -0
- package/src/acp/auto-install.ts +12 -8
- package/src/acp/failure-error.test.ts +109 -0
- package/src/acp/failure-error.ts +111 -0
- package/src/acp/prepare-agent-env.ts +0 -12
- package/src/acp/resolve-agent.test.ts +6 -45
- package/src/acp/resolve-agent.ts +2 -4
- package/src/acp/session-manager.test.ts +312 -0
- package/src/acp/session-manager.ts +102 -46
- package/src/agent/ax-tree-compaction.test.ts +4 -1
- package/src/agent/image-optimize.ts +17 -127
- package/src/agent/loop.ts +45 -192
- package/src/api/events/background-tool-completed.test.ts +51 -0
- package/src/api/events/background-tool-completed.ts +29 -0
- package/src/api/events/background-tool-started.test.ts +36 -0
- package/src/api/events/background-tool-started.ts +28 -0
- package/src/api/events/conversation-error.ts +0 -1
- package/src/api/events/open-panel.ts +33 -0
- package/src/api/events/subagent-status-changed.ts +4 -1
- package/src/api/index.ts +19 -0
- package/src/api/responses/conversation-message.ts +34 -0
- package/src/approvals/guardian-decision-primitive.ts +74 -24
- package/src/approvals/guardian-request-resolvers.ts +450 -122
- package/src/apps/app-store.ts +1 -0
- package/src/apps/shared-app-links-store.ts +1 -0
- package/src/avatar/identity-avatar.ts +3 -7
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
- package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +126 -102
- package/src/calls/call-controller.ts +134 -48
- package/src/calls/call-domain.ts +18 -42
- package/src/calls/call-pointer-messages.ts +51 -67
- package/src/calls/call-setup-flow-types.ts +76 -0
- package/src/calls/call-setup-flow.ts +1743 -0
- package/src/calls/call-speech-output.ts +87 -23
- package/src/calls/call-store.ts +4 -0
- package/src/calls/call-transport.ts +22 -36
- package/src/calls/fish-audio-client.ts +3 -0
- package/src/calls/gateway-invite-reader.ts +98 -0
- package/src/calls/guardian-wait-controller.ts +451 -0
- package/src/calls/media-stream-audio-transcode.ts +82 -2
- package/src/calls/media-stream-output.ts +142 -36
- package/src/calls/media-stream-server.ts +297 -178
- package/src/calls/media-stream-stt-session.ts +393 -50
- package/src/calls/media-turn-detector.ts +4 -6
- package/src/calls/relay-access-wait.ts +3 -4
- package/src/calls/relay-setup-router.ts +22 -43
- package/src/calls/relay-verification.ts +17 -24
- package/src/calls/resolve-call-tts-provider.ts +96 -29
- package/src/calls/stt-hints.ts +24 -87
- package/src/calls/telephony-credential-preflight.ts +159 -0
- package/src/calls/telephony-tts-capability.ts +183 -0
- package/src/calls/tts-call-strategy.ts +18 -20
- package/src/calls/twilio-provider.ts +3 -2
- package/src/calls/twilio-routes.ts +47 -351
- package/src/calls/types.ts +5 -3
- package/src/calls/voice-ingress-preflight.ts +9 -0
- package/src/calls/voice-quality.ts +13 -18
- package/src/calls/voice-session-bridge.ts +25 -35
- package/src/channels/__tests__/types.test.ts +28 -0
- package/src/channels/channel-verification-sessions.ts +7 -2
- package/src/channels/config.ts +0 -42
- package/src/channels/slack-thread-store.ts +12 -0
- package/src/channels/types.ts +23 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
- package/src/cli/commands/__tests__/schedules.test.ts +83 -34
- package/src/cli/commands/__tests__/status.test.ts +42 -2
- package/src/cli/commands/contacts.ts +2 -2
- package/src/cli/commands/credentials.ts +17 -0
- package/src/cli/commands/monitoring.ts +191 -0
- package/src/cli/commands/schedules-worker.ts +175 -0
- package/src/cli/commands/schedules.ts +169 -43
- package/src/cli/commands/status.ts +12 -1
- package/src/cli/commands/tools.ts +5 -1
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +7 -0
- package/src/cli/lib/search-plugins.ts +6 -0
- package/src/cli/lib/toggle-plugin.ts +21 -2
- package/src/cli/program.ts +3 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +23 -0
- package/src/config/acp-defaults.test.ts +0 -10
- package/src/config/acp-defaults.ts +0 -6
- package/src/config/bundled-skills/acp/SKILL.md +13 -45
- package/src/config/bundled-skills/acp/TOOLS.json +3 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
- package/src/config/bundled-skills/skill-management/TOOLS.json +10 -0
- package/src/config/call-site-defaults.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -8
- package/src/config/loader.ts +11 -0
- package/src/config/schema.ts +9 -1
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
- package/src/config/schemas/__tests__/memory-v3.test.ts +64 -0
- package/src/config/schemas/call-site-catalog.ts +0 -12
- package/src/config/schemas/calls.ts +8 -0
- package/src/config/schemas/elevenlabs.ts +1 -1
- package/src/config/schemas/llm.ts +0 -2
- package/src/config/schemas/memory-v2.ts +1 -1
- package/src/config/schemas/memory-v3.ts +82 -0
- package/src/config/schemas/monitoring.ts +61 -0
- package/src/config/schemas/schedules.ts +35 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills-plugin-filter.test.ts +96 -0
- package/src/config/skills.ts +26 -0
- package/src/contacts/__tests__/member-write-relay.test.ts +156 -4
- package/src/contacts/canonical-guardian-store.ts +5 -0
- package/src/contacts/contact-store.ts +81 -35
- package/src/contacts/contacts-write.ts +50 -25
- package/src/contacts/member-write-relay.ts +115 -31
- package/src/contacts/types.ts +0 -8
- package/src/context/compactor.ts +29 -15
- package/src/context/outbound-sanitize.ts +202 -0
- package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
- package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +122 -0
- package/src/daemon/__tests__/embedding-reconcile.test.ts +99 -16
- package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
- package/src/daemon/abort-watchdog.ts +7 -0
- package/src/daemon/app-source-watcher.ts +9 -0
- package/src/daemon/assistant-attachments.ts +42 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +256 -147
- package/src/daemon/conversation-agent-loop.ts +61 -68
- package/src/daemon/conversation-error.ts +1 -15
- package/src/daemon/conversation-history.ts +32 -236
- package/src/daemon/conversation-initial-prompt.ts +77 -0
- package/src/daemon/conversation-lifecycle.ts +25 -1
- package/src/daemon/conversation-messaging.ts +2 -2
- package/src/daemon/conversation-plugin-scope.ts +38 -0
- package/src/daemon/conversation-process.ts +50 -14
- package/src/daemon/conversation-runtime-assembly.ts +36 -6
- package/src/daemon/conversation-skill-tools.ts +19 -3
- package/src/daemon/conversation-store.ts +3 -3
- package/src/daemon/conversation-surfaces.ts +171 -0
- package/src/daemon/conversation-tool-setup.test.ts +95 -0
- package/src/daemon/conversation-tool-setup.ts +116 -1
- package/src/daemon/conversation-turn-finalize.ts +211 -0
- package/src/daemon/conversation.ts +92 -1
- package/src/daemon/disk-pressure-policy.ts +2 -1
- package/src/daemon/event-loop-watchdog.ts +22 -6
- package/src/daemon/external-plugins-bootstrap.ts +47 -134
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -5
- package/src/daemon/handlers/config-a2a.ts +7 -14
- package/src/daemon/handlers/config-channels.ts +2 -10
- package/src/daemon/handlers/conversation-history.ts +3 -1
- package/src/daemon/handlers/conversations.ts +0 -52
- package/src/daemon/handlers/shared.ts +4 -24
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +59 -472
- package/src/daemon/message-protocol.ts +3 -3
- package/src/daemon/message-provenance.ts +12 -14
- package/src/daemon/message-types/background-tools.ts +28 -0
- package/src/daemon/message-types/contacts.ts +2 -10
- package/src/daemon/message-types/conversations.ts +10 -0
- package/src/daemon/message-types/integrations.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pointer-conversation-trust.ts +23 -9
- package/src/daemon/pointer-turn-runner.ts +174 -0
- package/src/daemon/providers-setup.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +139 -47
- package/src/daemon/skill-memory-refresh.ts +2 -2
- package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
- package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
- package/src/daemon/tool-setup-types.ts +8 -0
- package/src/daemon/trust-context.ts +21 -6
- package/src/daemon/turn-latency-tracker.test.ts +93 -0
- package/src/daemon/turn-latency-tracker.ts +38 -0
- package/src/daemon/wake-conversation-ops.ts +10 -8
- package/src/documents/document-comments-store.test.ts +7 -1
- package/src/documents/document-comments-store.ts +8 -0
- package/src/documents/document-store.ts +15 -0
- package/src/export/__tests__/transcript-formatter.test.ts +11 -0
- package/src/export/transcript-formatter.ts +49 -67
- package/src/home/__tests__/feed-writer.test.ts +247 -1
- package/src/home/conversation-starter-checkpoints.ts +1 -0
- package/src/home/feed-writer.ts +61 -0
- package/src/home/job-handlers/conversation-starters.ts +1 -0
- package/src/hooks/hook-loader.ts +12 -0
- package/src/hooks/registry.ts +32 -4
- package/src/inbound/public-ingress-urls.ts +0 -17
- package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
- package/src/ipc/assistant-server.ts +28 -7
- package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
- package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
- package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
- package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
- package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
- package/src/ipc/routes/db-proxy.ts +5 -2
- package/src/ipc/routes/invite-ipc-routes.ts +53 -39
- package/src/jobs/worker.ts +9 -2
- package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
- package/src/live-voice/live-voice-archive.ts +5 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +22 -6
- package/src/messaging/providers/channel-transport.ts +6 -0
- package/src/messaging/providers/index.ts +3 -0
- package/src/messaging/providers/slack/api.test.ts +49 -1
- package/src/messaging/providers/slack/api.ts +110 -0
- package/src/messaging/providers/slack/send.test.ts +85 -0
- package/src/messaging/providers/slack/send.ts +100 -28
- package/src/messaging/providers/slack/transport.ts +7 -13
- package/src/messaging/providers/whatsapp/send.ts +29 -9
- package/src/monitoring/__tests__/control.test.ts +235 -0
- package/src/monitoring/__tests__/sample-ring-buffer.test.ts +96 -0
- package/src/monitoring/control.ts +105 -0
- package/src/monitoring/resource-sampler.ts +258 -0
- package/src/monitoring/sample-ring-buffer.ts +108 -0
- package/src/monitoring/worker.ts +94 -0
- package/src/notifications/README.md +1 -1
- package/src/notifications/access-request-copy.ts +94 -23
- package/src/notifications/adapters/slack.ts +89 -21
- package/src/notifications/approval-card-builder.ts +33 -18
- package/src/notifications/approval-card-data.ts +48 -15
- package/src/notifications/broadcaster.ts +25 -16
- package/src/notifications/decision-engine.ts +131 -32
- package/src/notifications/guardian-question-mode.ts +58 -10
- package/src/permissions/approval-policy.ts +8 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/gateway-threshold-reader.ts +7 -6
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/secret-prompter.ts +11 -3
- package/src/permissions/types.ts +2 -2
- package/src/persistence/__tests__/conversation-queries-search.test.ts +397 -0
- package/src/persistence/__tests__/conversation-search-lexical.test.ts +103 -0
- package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +95 -0
- package/src/persistence/__tests__/slow-query-log.test.ts +266 -0
- package/src/persistence/__tests__/slow-sync-log.test.ts +155 -0
- package/src/persistence/a2a-invite-store.ts +205 -0
- package/src/persistence/attachments-store.ts +94 -10
- package/src/persistence/checkpoints.ts +45 -0
- package/src/persistence/conversation-crud.ts +453 -260
- package/src/persistence/conversation-display-order-migration.ts +8 -2
- package/src/persistence/conversation-group-migration.test.ts +8 -0
- package/src/persistence/conversation-group-migration.ts +9 -0
- package/src/persistence/conversation-queries.ts +244 -125
- package/src/persistence/conversation-row-batch-delete.ts +9 -5
- package/src/persistence/conversation-search-lexical.ts +49 -0
- package/src/persistence/db-async-query.ts +42 -0
- package/src/persistence/db-connection.ts +13 -0
- package/src/persistence/delivery-channels.ts +0 -82
- package/src/persistence/delivery-crud.ts +27 -6
- package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +18 -5
- package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +334 -0
- package/src/persistence/embeddings/embedding-identity.ts +17 -5
- package/src/persistence/embeddings/embedding-runtime-manager.ts +31 -0
- package/src/persistence/embeddings/messages-lexical-index.ts +396 -0
- package/src/persistence/embeddings/qdrant-client.ts +81 -5
- package/src/persistence/group-crud.ts +13 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +506 -0
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +164 -0
- package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +259 -0
- package/src/persistence/job-handlers/cleanup.ts +57 -9
- package/src/persistence/job-handlers/message-lexical-backfill.ts +187 -0
- package/src/persistence/job-handlers/message-lexical.ts +251 -0
- package/src/persistence/jobs-store.ts +102 -8
- package/src/persistence/jobs-worker.ts +68 -28
- package/src/persistence/llm-request-log-store.ts +35 -19
- package/src/persistence/llm-usage-store.ts +11 -0
- package/src/persistence/memory-lifecycle-hooks.test.ts +65 -0
- package/src/persistence/memory-lifecycle-hooks.ts +55 -1
- package/src/persistence/migrations/028-call-session-mode.ts +1 -1
- package/src/persistence/migrations/116-messages-fts.ts +8 -1
- package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
- package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +15 -0
- package/src/persistence/migrations/313-drop-messages-fts.ts +17 -0
- package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +25 -0
- package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
- package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
- package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
- package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
- package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
- package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
- package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
- package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +99 -0
- package/src/persistence/raw-query.ts +50 -11
- package/src/persistence/schema/a2a.ts +14 -0
- package/src/persistence/schema/contacts.ts +0 -62
- package/src/persistence/schema/conversation-groups.ts +12 -0
- package/src/persistence/schema/conversations.ts +2 -0
- package/src/persistence/schema/documents.ts +65 -0
- package/src/persistence/schema/guardian.ts +4 -0
- package/src/persistence/schema/index.ts +4 -0
- package/src/persistence/schema/memory-injection.ts +62 -0
- package/src/persistence/schema/workflows.ts +55 -0
- package/src/persistence/slow-query-log.ts +437 -0
- package/src/persistence/slow-sync-log.ts +204 -0
- package/src/persistence/steps.ts +16 -0
- package/src/persistence/subagent-store.ts +125 -0
- package/src/persistence/worker-control.ts +45 -238
- package/src/plugin-api/event-hub-facade.ts +172 -0
- package/src/plugin-api/index.ts +9 -1
- package/src/plugin-api/types.ts +40 -9
- package/src/plugins/defaults/default-plugin-names.ts +60 -0
- package/src/plugins/defaults/index.ts +19 -29
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +46 -67
- package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +2 -4
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +9 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +7 -4
- package/src/plugins/defaults/memory/config.ts +11 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +124 -113
- package/src/plugins/defaults/memory/embeddings.ts +77 -0
- package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
- package/src/plugins/defaults/memory/frontmatter.ts +50 -0
- package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
- package/src/plugins/defaults/memory/graph/bootstrap.ts +6 -5
- package/src/plugins/defaults/memory/graph/consolidation.ts +3 -5
- package/src/plugins/defaults/memory/graph/extraction.ts +3 -6
- package/src/plugins/defaults/memory/graph/graph-search.ts +12 -23
- package/src/plugins/defaults/memory/graph/narrative.ts +3 -5
- package/src/plugins/defaults/memory/graph/pattern-scan.ts +3 -5
- package/src/plugins/defaults/memory/graph/retriever.test.ts +1 -6
- package/src/plugins/defaults/memory/graph/retriever.ts +5 -10
- package/src/plugins/defaults/memory/graph/tools.ts +1 -1
- package/src/plugins/defaults/memory/hooks/init.ts +31 -5
- package/src/plugins/defaults/memory/indexer.ts +2 -3
- package/src/plugins/defaults/memory/injectors.ts +2 -2
- package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
- package/src/plugins/defaults/memory/job-handlers/backfill.ts +4 -26
- package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +6 -19
- package/src/plugins/defaults/memory/job-handlers/embedding.ts +9 -22
- package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +2 -3
- package/src/plugins/defaults/memory/job-handlers.ts +13 -12
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
- package/src/plugins/defaults/memory/llm-helpers.ts +76 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +8 -5
- package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
- package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
- package/src/plugins/defaults/memory/persistence-hooks.ts +46 -1
- package/src/plugins/defaults/memory/pkb/pkb-index.ts +1 -5
- package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
- package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +4 -6
- package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
- package/src/plugins/defaults/memory/search/semantic.ts +2 -2
- package/src/plugins/defaults/memory/startup.ts +244 -0
- package/src/plugins/defaults/memory/task-memory-cleanup.ts +8 -0
- package/src/{daemon → plugins/defaults/memory/v2}/__tests__/memory-v2-startup.test.ts +6 -6
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +2 -13
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +4 -5
- package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +1 -8
- package/src/plugins/defaults/memory/v2/activation.ts +2 -4
- package/src/plugins/defaults/memory/v2/cli-command-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.test.ts +8 -8
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.ts +20 -22
- package/src/plugins/defaults/memory/v2/migration.ts +2 -5
- package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
- package/src/plugins/defaults/memory/v2/qdrant.ts +2 -3
- package/src/plugins/defaults/memory/v2/router.ts +5 -5
- package/src/plugins/defaults/memory/v2/sim.ts +2 -4
- package/src/plugins/defaults/memory/v2/skill-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +11 -9
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +107 -2
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +69 -0
- package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +181 -0
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +7 -3
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +345 -8
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -4
- package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +64 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +18 -13
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +62 -1
- package/src/plugins/defaults/memory/v3/card.ts +1 -4
- package/src/plugins/defaults/memory/v3/dense.ts +60 -25
- package/src/plugins/defaults/memory/v3/edge.ts +1 -1
- package/src/plugins/defaults/memory/v3/gate-flag.ts +20 -0
- package/src/plugins/defaults/memory/v3/gate.ts +158 -0
- package/src/plugins/defaults/memory/v3/maintain-job.ts +2 -4
- package/src/plugins/defaults/memory/v3/orchestrate.ts +186 -25
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +7 -9
- package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
- package/src/plugins/defaults/memory/v3/prune.ts +2 -2
- package/src/plugins/defaults/memory/v3/section-dense-store.ts +8 -11
- package/src/plugins/defaults/memory/v3/section-needle.ts +27 -7
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +10 -0
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +1 -4
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +5 -0
- package/src/plugins/defaults/turn-context/injectors.ts +1 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +12 -0
- package/src/plugins/injector-registry.ts +13 -2
- package/src/plugins/mtime-cache.ts +36 -47
- package/src/plugins/pipeline.ts +15 -1
- package/src/plugins/types.ts +14 -23
- package/src/prompts/__tests__/system-prompt.test.ts +170 -32
- package/src/prompts/persona-resolver.ts +13 -9
- package/src/prompts/system-prompt.ts +30 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -119
- package/src/prompts/templates/SOUL.md +43 -13
- package/src/prompts/templates/system-sections.ts +32 -27
- package/src/prompts/templates/users/default.md +19 -0
- package/src/providers/__tests__/placeholder-sentinels.test.ts +56 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +14 -1
- package/src/providers/openai/responses-provider.ts +18 -0
- package/src/providers/placeholder-sentinels.ts +18 -8
- package/src/providers/retry.ts +1 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
- package/src/providers/speech-to-text/provider-catalog.ts +0 -89
- package/src/providers/speech-to-text/resolve.ts +55 -0
- package/src/providers/tool-progress-events.test.ts +50 -0
- package/src/providers/tool-progress-events.ts +99 -0
- package/src/providers/types.ts +1 -1
- package/src/providers/vellum-model-routing.test.ts +51 -0
- package/src/providers/vellum-model-routing.ts +84 -0
- package/src/runtime/AGENTS.md +5 -4
- package/src/runtime/__tests__/agent-wake.test.ts +158 -1
- package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
- package/src/runtime/access-request-helper.ts +154 -3
- package/src/runtime/actor-trust-resolver.ts +7 -21
- package/src/runtime/agent-wake.ts +41 -1
- package/src/runtime/assistant-event.ts +86 -12
- package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
- package/src/runtime/channel-approval-types.ts +52 -2
- package/src/runtime/channel-approvals.ts +23 -8
- package/src/runtime/channel-invite-transport.ts +2 -2
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-readiness-service.ts +3 -5
- package/src/runtime/channel-retry-sweep.ts +18 -24
- package/src/runtime/channel-verification-service.ts +9 -11
- package/src/runtime/finalize-event-delivery.ts +30 -16
- package/src/runtime/guardian-action-service.ts +10 -11
- package/src/runtime/guardian-reply-router.ts +122 -21
- package/src/runtime/http-server.ts +44 -101
- package/src/runtime/introduction-policy.test.ts +214 -0
- package/src/runtime/introduction-policy.ts +284 -0
- package/src/runtime/invite-service.ts +104 -361
- package/src/runtime/local-actor-identity.test.ts +38 -0
- package/src/runtime/local-actor-identity.ts +14 -0
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +22 -0
- package/src/runtime/middleware/rate-limiter.ts +30 -0
- package/src/runtime/middleware/twilio-validation.ts +5 -7
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
- package/src/runtime/migrations/origin-mode.ts +6 -6
- package/src/runtime/pre-first-message-gate.ts +1 -0
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +6 -35
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
- package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +142 -1
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
- package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +194 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +755 -29
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
- package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +70 -0
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +161 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
- package/src/runtime/routes/acp-routes.ts +15 -3
- package/src/runtime/routes/app-management-routes.ts +4 -7
- package/src/runtime/routes/approval-routes.ts +4 -0
- package/src/runtime/routes/attachment-routes.ts +54 -3
- package/src/runtime/routes/avatar-routes.ts +0 -4
- package/src/runtime/routes/background-tool-routes.ts +34 -5
- package/src/runtime/routes/btw-routes.ts +32 -4
- package/src/runtime/routes/channel-route-shared.ts +18 -14
- package/src/runtime/routes/channel-verification-routes.ts +0 -3
- package/src/runtime/routes/contact-routes.ts +298 -117
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +74 -37
- package/src/runtime/routes/conversation-query-routes.ts +5 -2
- package/src/runtime/routes/conversation-routes.ts +222 -82
- package/src/runtime/routes/conversations-import-routes.ts +8 -1
- package/src/runtime/routes/credential-prompt-routes.ts +20 -5
- package/src/runtime/routes/debug-routes.ts +1 -0
- package/src/runtime/routes/documents-routes.ts +5 -2
- package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
- package/src/runtime/routes/global-search-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +51 -0
- package/src/runtime/routes/home-feed-routes.ts +60 -1
- package/src/runtime/routes/identity-routes.ts +4 -87
- package/src/runtime/routes/inbound-message-handler.ts +82 -41
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +430 -57
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +302 -572
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +76 -270
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +21 -116
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +9 -1
- package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +158 -0
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +22 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +22 -16
- package/src/runtime/routes/internal-twilio-routes.ts +0 -15
- package/src/runtime/routes/messages-lexical-routes.ts +75 -0
- package/src/runtime/routes/migration-routes.ts +69 -6
- package/src/runtime/routes/monitoring-routes.ts +237 -0
- package/src/runtime/routes/plugins-routes.ts +329 -8
- package/src/runtime/routes/schedule-routes.ts +49 -8
- package/src/runtime/routes/schedule-worker-routes.ts +210 -0
- package/src/runtime/routes/secret-routes.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
- package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +30 -6
- package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +43 -8
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +20 -0
- package/src/runtime/services/analyze-conversation.ts +14 -4
- package/src/runtime/services/conversation-serializer.ts +5 -0
- package/src/runtime/slack-no-response.ts +47 -0
- package/src/runtime/slack-reply-session.test.ts +633 -0
- package/src/runtime/slack-reply-session.ts +382 -0
- package/src/runtime/slack-task-progress.ts +95 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/tool-grant-request-helper.ts +17 -1
- package/src/runtime/trust-class.test.ts +141 -0
- package/src/runtime/trust-class.ts +121 -0
- package/src/runtime/trust-verdict-consumer.ts +7 -6
- package/src/schedule/__tests__/run-script.test.ts +21 -0
- package/src/schedule/__tests__/worker-control.test.ts +241 -0
- package/src/schedule/run-script.ts +13 -6
- package/src/schedule/schedule-usage-store.ts +1 -0
- package/src/schedule/scheduler.ts +178 -127
- package/src/schedule/worker-control.ts +118 -0
- package/src/schedule/worker.ts +131 -0
- package/src/skills/__tests__/categories-cache.test.ts +38 -0
- package/src/skills/categories-cache.ts +40 -5
- package/src/skills/managed-store.ts +41 -6
- package/src/skills/validate-input.ts +47 -0
- package/src/stt/types.ts +5 -9
- package/src/subagent/manager.ts +267 -39
- package/src/subagent/types.ts +6 -2
- package/src/subagent/validate-allowlists.ts +65 -0
- package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
- package/src/telemetry/watchdog-direct-emit.ts +89 -0
- package/src/tools/acp/list-agents.test.ts +0 -6
- package/src/tools/background-tool-registry.ts +61 -0
- package/src/tools/document/document-comment-tool.test.ts +4 -0
- package/src/tools/host-terminal/host-shell.test.ts +397 -0
- package/src/tools/host-terminal/host-shell.ts +203 -14
- package/src/tools/skills/find-similar-skills.test.ts +152 -1
- package/src/tools/skills/find-similar-skills.ts +30 -4
- package/src/tools/skills/load.ts +36 -0
- package/src/tools/skills/scaffold-managed.ts +66 -34
- package/src/tools/skills/skill-script-runner.ts +17 -0
- package/src/tools/skills/skill-tool-factory.ts +5 -1
- package/src/tools/terminal/safe-env.ts +3 -0
- package/src/tools/terminal/shell.test.ts +177 -0
- package/src/tools/terminal/shell.ts +98 -4
- package/src/tools/tool-approval-handler.ts +106 -29
- package/{node_modules/@vellumai/skill-host-contracts/src → src/tools}/tool-types.ts +16 -17
- package/src/tools/types.ts +29 -17
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/tts/__tests__/provider-adapters.test.ts +37 -0
- package/src/tts/__tests__/provider-catalog.test.ts +21 -0
- package/src/tts/provider-catalog.ts +40 -9
- package/src/tts/providers/fish-audio-provider.ts +19 -10
- package/src/tts/types.ts +3 -4
- package/src/util/__tests__/process-tree.test.ts +10 -2
- package/src/util/__tests__/text-spacing.test.ts +53 -0
- package/src/util/cgroup-memory.ts +142 -0
- package/src/util/image-conversion.ts +281 -0
- package/src/util/phone.ts +1 -8
- package/src/util/platform.ts +33 -0
- package/src/util/process-tree.ts +10 -2
- package/src/util/text-spacing.ts +53 -0
- package/src/util/worker-process.ts +271 -0
- package/src/workflows/journal-store.ts +16 -1
- package/src/workflows/library.test.ts +35 -20
- package/src/workflows/library.ts +105 -66
- package/src/workspace/git-service.ts +1 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +83 -31
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +41 -22
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
- package/src/workspace/migrations/118-seed-now-md.ts +64 -0
- package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +169 -0
- package/src/workspace/migrations/120-revise-onboarding-threads.ts +47 -0
- package/src/workspace/migrations/121-seed-default-user-guardrails.ts +82 -0
- package/src/workspace/migrations/122-relocate-default-user-boundary.ts +111 -0
- package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +85 -0
- package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +181 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/drizzle/0000_dizzy_maggott.sql +0 -301
- package/drizzle/meta/0000_snapshot.json +0 -1933
- package/drizzle/meta/_journal.json +0 -13
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
- package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
- package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
- package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
- package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
- package/src/__tests__/invite-redemption-service.test.ts +0 -1180
- package/src/__tests__/invite-service-ipc.test.ts +0 -350
- package/src/__tests__/job-handler-registry-guard.test.ts +0 -125
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
- package/src/__tests__/relay-server.test.ts +0 -6153
- package/src/__tests__/telephony-stt-routing.test.ts +0 -329
- package/src/__tests__/voice-invite-redemption.test.ts +0 -702
- package/src/calls/relay-server.ts +0 -2463
- package/src/calls/telephony-stt-routing.ts +0 -145
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
- package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
- package/src/daemon/daemon-skill-host.ts +0 -262
- package/src/daemon/message-types/meet.ts +0 -143
- package/src/daemon/shutdown-registry.ts +0 -40
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
- package/src/ipc/__tests__/skill-server.test.ts +0 -182
- package/src/ipc/skill-ipc-types.ts +0 -54
- package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
- package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
- package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
- package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
- package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
- package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
- package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
- package/src/ipc/skill-routes/config.ts +0 -47
- package/src/ipc/skill-routes/events.ts +0 -147
- package/src/ipc/skill-routes/identity.ts +0 -21
- package/src/ipc/skill-routes/index.ts +0 -37
- package/src/ipc/skill-routes/log.ts +0 -40
- package/src/ipc/skill-routes/memory.ts +0 -92
- package/src/ipc/skill-routes/platform.ts +0 -39
- package/src/ipc/skill-routes/providers.ts +0 -162
- package/src/ipc/skill-routes/registries.ts +0 -338
- package/src/ipc/skill-server.ts +0 -831
- package/src/ipc/skill-socket-path.ts +0 -20
- package/src/jobs/register-job-handlers.ts +0 -74
- package/src/persistence/invite-store.ts +0 -481
- package/src/plugins/job-handler-registry.ts +0 -94
- package/src/providers/cache-control.ts +0 -26
- package/src/runtime/__tests__/runtime-mode.test.ts +0 -62
- package/src/runtime/invite-redemption-service.ts +0 -828
- package/src/runtime/invite-redemption-templates.ts +0 -46
- package/src/runtime/runtime-mode.ts +0 -40
- package/src/runtime/slack-dm-text-delivery.ts +0 -177
- package/src/util/voice-code.ts +0 -31
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { beforeAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import type { SparseEmbedding } from "../../embeddings/embedding-types.js";
|
|
4
|
+
|
|
5
|
+
mock.module("../../../util/logger.js", () => ({
|
|
6
|
+
getLogger: () =>
|
|
7
|
+
new Proxy({} as Record<string, unknown>, {
|
|
8
|
+
get: () => () => {},
|
|
9
|
+
}),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
// Capture calls into the lexical index singleton.
|
|
13
|
+
const upsertCalls: Array<{
|
|
14
|
+
messageId: string;
|
|
15
|
+
sparse: SparseEmbedding;
|
|
16
|
+
payload: { conversationId: string; createdAt: number };
|
|
17
|
+
}> = [];
|
|
18
|
+
const deleteByConversationCalls: string[] = [];
|
|
19
|
+
|
|
20
|
+
const fakeIndex = {
|
|
21
|
+
upsertMessage: async (
|
|
22
|
+
messageId: string,
|
|
23
|
+
sparse: SparseEmbedding,
|
|
24
|
+
payload: { conversationId: string; createdAt: number },
|
|
25
|
+
) => {
|
|
26
|
+
upsertCalls.push({ messageId, sparse, payload });
|
|
27
|
+
},
|
|
28
|
+
deleteByConversation: async (conversationId: string) => {
|
|
29
|
+
deleteByConversationCalls.push(conversationId);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Model the process-local singleton so the worker scenario (init never ran in
|
|
34
|
+
// this process) is exercisable: getMessagesLexicalIndex throws until
|
|
35
|
+
// initMessagesLexicalIndex sets it, mirroring the real module's behavior.
|
|
36
|
+
let singletonReady = true;
|
|
37
|
+
const initConfigCalls: Array<{
|
|
38
|
+
url: string;
|
|
39
|
+
collection?: string;
|
|
40
|
+
onDisk?: boolean;
|
|
41
|
+
}> = [];
|
|
42
|
+
|
|
43
|
+
function resetLexicalSingleton(ready: boolean): void {
|
|
44
|
+
singletonReady = ready;
|
|
45
|
+
initConfigCalls.length = 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
mock.module("../../embeddings/messages-lexical-index.js", () => ({
|
|
49
|
+
MESSAGES_LEXICAL_COLLECTION: "messages_lexical",
|
|
50
|
+
getMessagesLexicalIndex: () => {
|
|
51
|
+
if (!singletonReady) {
|
|
52
|
+
throw new Error("Messages lexical index not initialized.");
|
|
53
|
+
}
|
|
54
|
+
return fakeIndex;
|
|
55
|
+
},
|
|
56
|
+
initMessagesLexicalIndex: (config: {
|
|
57
|
+
url: string;
|
|
58
|
+
collection?: string;
|
|
59
|
+
onDisk?: boolean;
|
|
60
|
+
}) => {
|
|
61
|
+
initConfigCalls.push(config);
|
|
62
|
+
singletonReady = true;
|
|
63
|
+
return fakeIndex;
|
|
64
|
+
},
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
// `generateSparseEmbedding` is a pure local TF-IDF encoder (no provider call),
|
|
68
|
+
// so it runs unmocked — mocking `embedding-backend.js` wholesale would starve
|
|
69
|
+
// its other named exports that the db-init import graph pulls in.
|
|
70
|
+
import { resetDbForTesting } from "../../../__tests__/db-test-helpers.js";
|
|
71
|
+
import { DEFAULT_CONFIG } from "../../../config/defaults.js";
|
|
72
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
73
|
+
import { getDb } from "../../db-connection.js";
|
|
74
|
+
import { initializeDb } from "../../db-init.js";
|
|
75
|
+
import { generateSparseEmbedding } from "../../embeddings/embedding-backend.js";
|
|
76
|
+
import type { MemoryJob } from "../../jobs-store.js";
|
|
77
|
+
import { conversations, messages } from "../../schema/index.js";
|
|
78
|
+
import {
|
|
79
|
+
indexMessageLexicalJob,
|
|
80
|
+
purgeConversationLexicalJob,
|
|
81
|
+
} from "../message-lexical.js";
|
|
82
|
+
|
|
83
|
+
const TEST_CONFIG: AssistantConfig = DEFAULT_CONFIG;
|
|
84
|
+
|
|
85
|
+
function makeJob(
|
|
86
|
+
type: MemoryJob["type"],
|
|
87
|
+
payload: Record<string, unknown>,
|
|
88
|
+
): MemoryJob {
|
|
89
|
+
return {
|
|
90
|
+
id: "job-1",
|
|
91
|
+
type,
|
|
92
|
+
payload,
|
|
93
|
+
status: "running",
|
|
94
|
+
attempts: 0,
|
|
95
|
+
deferrals: 0,
|
|
96
|
+
runAfter: 0,
|
|
97
|
+
lastError: null,
|
|
98
|
+
startedAt: Date.now(),
|
|
99
|
+
createdAt: Date.now(),
|
|
100
|
+
updatedAt: Date.now(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function insertConversation(id: string): void {
|
|
105
|
+
const now = Date.now();
|
|
106
|
+
getDb()
|
|
107
|
+
.insert(conversations)
|
|
108
|
+
.values({ id, createdAt: now, updatedAt: now })
|
|
109
|
+
.run();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function insertMessage(opts: {
|
|
113
|
+
id: string;
|
|
114
|
+
conversationId: string;
|
|
115
|
+
content: string;
|
|
116
|
+
createdAt: number;
|
|
117
|
+
}): void {
|
|
118
|
+
getDb()
|
|
119
|
+
.insert(messages)
|
|
120
|
+
.values({
|
|
121
|
+
id: opts.id,
|
|
122
|
+
conversationId: opts.conversationId,
|
|
123
|
+
role: "user",
|
|
124
|
+
content: opts.content,
|
|
125
|
+
createdAt: opts.createdAt,
|
|
126
|
+
})
|
|
127
|
+
.run();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
describe("indexMessageLexicalJob", () => {
|
|
131
|
+
// initializeDb runs the full migration chain; under parallel CI load it can
|
|
132
|
+
// exceed bun's default 5s hook timeout, so allow more.
|
|
133
|
+
beforeAll(async () => {
|
|
134
|
+
await initializeDb();
|
|
135
|
+
}, 30_000);
|
|
136
|
+
|
|
137
|
+
beforeEach(async () => {
|
|
138
|
+
upsertCalls.length = 0;
|
|
139
|
+
deleteByConversationCalls.length = 0;
|
|
140
|
+
resetLexicalSingleton(true);
|
|
141
|
+
resetDbForTesting();
|
|
142
|
+
await initializeDb();
|
|
143
|
+
}, 30_000);
|
|
144
|
+
|
|
145
|
+
test("loads the message and upserts it into the lexical index", async () => {
|
|
146
|
+
const createdAt = 1_700_000_000_000;
|
|
147
|
+
const content = "hello lexical world";
|
|
148
|
+
insertConversation("conv-1");
|
|
149
|
+
insertMessage({
|
|
150
|
+
id: "msg-1",
|
|
151
|
+
conversationId: "conv-1",
|
|
152
|
+
content,
|
|
153
|
+
createdAt,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await indexMessageLexicalJob(
|
|
157
|
+
makeJob("index_message_lexical", { messageId: "msg-1" }),
|
|
158
|
+
TEST_CONFIG,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(upsertCalls).toHaveLength(1);
|
|
162
|
+
expect(upsertCalls[0].messageId).toBe("msg-1");
|
|
163
|
+
// The handler encodes the message content via the local sparse encoder.
|
|
164
|
+
expect(upsertCalls[0].sparse).toEqual(generateSparseEmbedding(content));
|
|
165
|
+
expect(upsertCalls[0].payload).toEqual({
|
|
166
|
+
conversationId: "conv-1",
|
|
167
|
+
createdAt,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("no-ops when messageId is missing from the payload", async () => {
|
|
172
|
+
await indexMessageLexicalJob(
|
|
173
|
+
makeJob("index_message_lexical", {}),
|
|
174
|
+
TEST_CONFIG,
|
|
175
|
+
);
|
|
176
|
+
expect(upsertCalls).toHaveLength(0);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("no-ops when the message no longer exists", async () => {
|
|
180
|
+
await indexMessageLexicalJob(
|
|
181
|
+
makeJob("index_message_lexical", { messageId: "nonexistent" }),
|
|
182
|
+
TEST_CONFIG,
|
|
183
|
+
);
|
|
184
|
+
expect(upsertCalls).toHaveLength(0);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("lazily initializes the index from config when not yet initialized (worker process)", async () => {
|
|
188
|
+
// Simulate the out-of-process worker, which never runs runMemoryStartup —
|
|
189
|
+
// the singleton is not initialized in this process.
|
|
190
|
+
resetLexicalSingleton(false);
|
|
191
|
+
|
|
192
|
+
const createdAt = 1_700_000_000_001;
|
|
193
|
+
insertConversation("conv-w");
|
|
194
|
+
insertMessage({
|
|
195
|
+
id: "msg-w",
|
|
196
|
+
conversationId: "conv-w",
|
|
197
|
+
content: "indexed by the worker",
|
|
198
|
+
createdAt,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
await indexMessageLexicalJob(
|
|
202
|
+
makeJob("index_message_lexical", { messageId: "msg-w" }),
|
|
203
|
+
TEST_CONFIG,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// The handler initialized the index from config instead of throwing.
|
|
207
|
+
expect(initConfigCalls).toHaveLength(1);
|
|
208
|
+
expect(initConfigCalls[0]).toEqual({
|
|
209
|
+
url: TEST_CONFIG.memory.qdrant.url,
|
|
210
|
+
collection: "messages_lexical",
|
|
211
|
+
onDisk: TEST_CONFIG.memory.qdrant.onDisk,
|
|
212
|
+
});
|
|
213
|
+
// ...and proceeded to index the message.
|
|
214
|
+
expect(upsertCalls).toHaveLength(1);
|
|
215
|
+
expect(upsertCalls[0].messageId).toBe("msg-w");
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe("purgeConversationLexicalJob", () => {
|
|
220
|
+
beforeAll(async () => {
|
|
221
|
+
await initializeDb();
|
|
222
|
+
}, 30_000);
|
|
223
|
+
|
|
224
|
+
beforeEach(async () => {
|
|
225
|
+
upsertCalls.length = 0;
|
|
226
|
+
deleteByConversationCalls.length = 0;
|
|
227
|
+
resetLexicalSingleton(true);
|
|
228
|
+
resetDbForTesting();
|
|
229
|
+
await initializeDb();
|
|
230
|
+
}, 30_000);
|
|
231
|
+
|
|
232
|
+
test("deletes the conversation's points from the lexical index", async () => {
|
|
233
|
+
await purgeConversationLexicalJob(
|
|
234
|
+
makeJob("purge_conversation_lexical", { conversationId: "conv-9" }),
|
|
235
|
+
TEST_CONFIG,
|
|
236
|
+
);
|
|
237
|
+
expect(deleteByConversationCalls).toEqual(["conv-9"]);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("no-ops when conversationId is missing from the payload", async () => {
|
|
241
|
+
await purgeConversationLexicalJob(
|
|
242
|
+
makeJob("purge_conversation_lexical", {}),
|
|
243
|
+
TEST_CONFIG,
|
|
244
|
+
);
|
|
245
|
+
expect(deleteByConversationCalls).toHaveLength(0);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test("lazily initializes the index from config when not yet initialized (worker process)", async () => {
|
|
249
|
+
resetLexicalSingleton(false);
|
|
250
|
+
|
|
251
|
+
await purgeConversationLexicalJob(
|
|
252
|
+
makeJob("purge_conversation_lexical", { conversationId: "conv-w" }),
|
|
253
|
+
TEST_CONFIG,
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
expect(initConfigCalls).toHaveLength(1);
|
|
257
|
+
expect(deleteByConversationCalls).toEqual(["conv-w"]);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AssistantConfig } from "../../config/types.js";
|
|
2
|
+
import { rotateToolInvocations } from "../../telemetry/tool-usage-store.js";
|
|
2
3
|
import { getLogger } from "../../util/logger.js";
|
|
3
4
|
import { getLogsDbPath } from "../../util/logs-db-path.js";
|
|
4
5
|
import { runAsyncSqlite } from "../db-async-query.js";
|
|
@@ -139,6 +140,32 @@ SELECT changes();`,
|
|
|
139
140
|
);
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Delete audit-log (`tool_invocations`) entries older than the configured
|
|
145
|
+
* retention window. Retention comes from `auditLog.retentionDays` (0 = keep
|
|
146
|
+
* forever). The DELETE itself lives in {@link rotateToolInvocations}; this
|
|
147
|
+
* handler just resolves the window and dispatches, mirroring the other
|
|
148
|
+
* scheduled cleanup jobs.
|
|
149
|
+
*/
|
|
150
|
+
export async function pruneOldToolInvocationsJob(
|
|
151
|
+
job: MemoryJob,
|
|
152
|
+
config: AssistantConfig,
|
|
153
|
+
): Promise<void> {
|
|
154
|
+
const rawRetention = job.payload.retentionDays;
|
|
155
|
+
const retentionDays =
|
|
156
|
+
typeof rawRetention === "number" &&
|
|
157
|
+
Number.isFinite(rawRetention) &&
|
|
158
|
+
rawRetention >= 0
|
|
159
|
+
? rawRetention
|
|
160
|
+
: config.auditLog.retentionDays;
|
|
161
|
+
|
|
162
|
+
// 0 means disabled. rotateToolInvocations no-ops on this too, but
|
|
163
|
+
// short-circuit so we don't dispatch a pointless async query.
|
|
164
|
+
if (!retentionDays) return;
|
|
165
|
+
|
|
166
|
+
await rotateToolInvocations(retentionDays);
|
|
167
|
+
}
|
|
168
|
+
|
|
142
169
|
/**
|
|
143
170
|
* Parse the `SELECT changes()` result emitted by the sqlite3 CLI after
|
|
144
171
|
* the prune DELETE. Returns 0 if stdout is missing or unparseable —
|
|
@@ -170,10 +197,9 @@ function parseDeletedCount(stdout: string | undefined): number {
|
|
|
170
197
|
*
|
|
171
198
|
* Tables with onDelete cascade on conversation FK (memory_segments,
|
|
172
199
|
* conversation_keys, channel_inbound_events, message_runs, call_sessions,
|
|
173
|
-
* external_conversation_bindings
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* removing the conversation row.
|
|
200
|
+
* external_conversation_bindings) are handled automatically. Tables without
|
|
201
|
+
* cascade (messages, tool_invocations, llm_request_logs, skill_loaded_events)
|
|
202
|
+
* are deleted explicitly before removing the conversation row.
|
|
177
203
|
*/
|
|
178
204
|
export function pruneOldConversationsJob(
|
|
179
205
|
job: MemoryJob,
|
|
@@ -192,6 +218,7 @@ export function pruneOldConversationsJob(
|
|
|
192
218
|
const cutoffMs = Date.now() - retentionDays * 86_400_000;
|
|
193
219
|
|
|
194
220
|
const stale = rawAll<{ id: string }>(
|
|
221
|
+
"cleanup:pruneOldConversations:stale",
|
|
195
222
|
`SELECT id FROM conversations WHERE updated_at < ? ORDER BY updated_at ASC LIMIT ?`,
|
|
196
223
|
cutoffMs,
|
|
197
224
|
PRUNE_BATCH_LIMIT,
|
|
@@ -205,6 +232,7 @@ export function pruneOldConversationsJob(
|
|
|
205
232
|
// Re-check staleness inside the transaction to avoid racing with a conversation
|
|
206
233
|
// that became active again between the initial SELECT and this DELETE.
|
|
207
234
|
const still = rawAll<{ id: string }>(
|
|
235
|
+
"cleanup:pruneOldConversations:recheck",
|
|
208
236
|
`SELECT id FROM conversations WHERE id = ? AND updated_at < ?`,
|
|
209
237
|
id,
|
|
210
238
|
cutoffMs,
|
|
@@ -213,12 +241,32 @@ export function pruneOldConversationsJob(
|
|
|
213
241
|
|
|
214
242
|
// Non-cascading tables. llm_request_logs lives in the dedicated logs
|
|
215
243
|
// connection, so it is deleted there (outside this main-DB transaction).
|
|
216
|
-
rawLogsRun(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
244
|
+
rawLogsRun(
|
|
245
|
+
"cleanup:pruneOldConversations:logs",
|
|
246
|
+
`DELETE FROM llm_request_logs WHERE conversation_id = ?`,
|
|
247
|
+
id,
|
|
248
|
+
);
|
|
249
|
+
rawRun(
|
|
250
|
+
"cleanup:pruneOldConversations:toolInv",
|
|
251
|
+
`DELETE FROM tool_invocations WHERE conversation_id = ?`,
|
|
252
|
+
id,
|
|
253
|
+
);
|
|
254
|
+
rawRun(
|
|
255
|
+
"cleanup:pruneOldConversations:messages",
|
|
256
|
+
`DELETE FROM messages WHERE conversation_id = ?`,
|
|
257
|
+
id,
|
|
258
|
+
);
|
|
259
|
+
rawRun(
|
|
260
|
+
"cleanup:pruneOldConversations:skills",
|
|
261
|
+
`DELETE FROM skill_loaded_events WHERE conversation_id = ?`,
|
|
262
|
+
id,
|
|
263
|
+
);
|
|
220
264
|
// Conversation row deletion cascades to remaining dependent tables
|
|
221
|
-
rawRun(
|
|
265
|
+
rawRun(
|
|
266
|
+
"cleanup:pruneOldConversations:conv",
|
|
267
|
+
`DELETE FROM conversations WHERE id = ?`,
|
|
268
|
+
id,
|
|
269
|
+
);
|
|
222
270
|
pruned++;
|
|
223
271
|
});
|
|
224
272
|
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { and, asc, eq, gt, or } from "drizzle-orm";
|
|
2
|
+
|
|
3
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
4
|
+
import { getLogger } from "../../util/logger.js";
|
|
5
|
+
import {
|
|
6
|
+
clearLexicalBackfillComplete,
|
|
7
|
+
isLexicalBackfillComplete,
|
|
8
|
+
LEXICAL_BACKFILL_COMPLETE_KEY,
|
|
9
|
+
readMessageCursorCheckpoint,
|
|
10
|
+
resetMessageCursorCheckpoint,
|
|
11
|
+
setMemoryCheckpoint,
|
|
12
|
+
writeMessageCursorCheckpoint,
|
|
13
|
+
} from "../checkpoints.js";
|
|
14
|
+
import { getDb } from "../db-connection.js";
|
|
15
|
+
import { generateSparseEmbedding } from "../embeddings/embedding-backend.js";
|
|
16
|
+
import { withQdrantBreaker } from "../embeddings/qdrant-circuit-breaker.js";
|
|
17
|
+
import {
|
|
18
|
+
enqueueMemoryJob,
|
|
19
|
+
hasActiveJobOfType,
|
|
20
|
+
type MemoryJob,
|
|
21
|
+
} from "../jobs-store.js";
|
|
22
|
+
import { messages } from "../schema/index.js";
|
|
23
|
+
import { resolveLexicalIndex } from "./message-lexical.js";
|
|
24
|
+
|
|
25
|
+
const log = getLogger("lexical-backfill");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Cursor checkpoint keys for the lexical-index backfill. Kept distinct from the
|
|
29
|
+
* dense embedding backfill's keys (`memory:backfill:*`) so the two backfills
|
|
30
|
+
* advance independently — enabling lexical without re-running the dense one, and
|
|
31
|
+
* vice versa.
|
|
32
|
+
*/
|
|
33
|
+
const LEXICAL_BACKFILL_CHECKPOINT_KEY = "lexical:messages:last_created_at";
|
|
34
|
+
const LEXICAL_BACKFILL_CHECKPOINT_ID_KEY = "lexical:messages:last_id";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* One-time, self-healing auto-enqueue of the messages lexical-index backfill,
|
|
38
|
+
* invoked once from daemon startup (`daemon/lifecycle.ts`). Ensures each
|
|
39
|
+
* instance populates its Qdrant lexical index (`messages_lexical`) exactly once
|
|
40
|
+
* on upgrade — in the background — so message-content search does not open
|
|
41
|
+
* onto an empty index.
|
|
42
|
+
*
|
|
43
|
+
* Deliberate, narrow exception to the "not run at daemon startup" note carried by
|
|
44
|
+
* the manual backfill route (`messages-lexical-routes.ts`, added in the FTS→Qdrant
|
|
45
|
+
* PR 5): this call only *enqueues* a memory job — it does no indexing, no LLM
|
|
46
|
+
* work, and no other heavy lifting on the boot thread. The backfill itself runs
|
|
47
|
+
* off the event loop via the existing memory job worker, in small
|
|
48
|
+
* cursor-checkpointed batches. It is a one-time, checkpoint-guarded, no-LLM data
|
|
49
|
+
* backfill (migration-like), so it is consistent with the daemon-startup
|
|
50
|
+
* philosophy of never blocking or doing expensive work at boot.
|
|
51
|
+
*
|
|
52
|
+
* Guards (all must pass to enqueue):
|
|
53
|
+
* - The completion sentinel must be unset. Once the backfill has fully drained
|
|
54
|
+
* on this instance there is nothing to do; the marker makes this idempotent
|
|
55
|
+
* across restarts.
|
|
56
|
+
* - No backfill job may already be pending or running. Without this, every
|
|
57
|
+
* restart during a long backfill would pile up a duplicate job. (The batches
|
|
58
|
+
* are idempotent, but redundant jobs waste worker cycles.)
|
|
59
|
+
*
|
|
60
|
+
* Unconditional beyond those guards: message-content search is host
|
|
61
|
+
* infrastructure, so the backfill runs regardless of the memory feature's or
|
|
62
|
+
* memory plugin's state (the job worker drains the lexical types even while
|
|
63
|
+
* memory is disabled).
|
|
64
|
+
*
|
|
65
|
+
* An instance that was already manually backfilled via the route but predates
|
|
66
|
+
* the completion sentinel re-enqueues once here and re-runs the idempotent
|
|
67
|
+
* backfill (no duplicate points; ~minutes) — an acceptable one-time cost.
|
|
68
|
+
*
|
|
69
|
+
* Best-effort and lightweight: any failure (e.g. the memory database is briefly
|
|
70
|
+
* unavailable at boot) is swallowed and logged so a memory hiccup never blocks
|
|
71
|
+
* daemon startup, matching the surrounding startup steps.
|
|
72
|
+
*/
|
|
73
|
+
export function maybeEnqueueLexicalBackfillOnUpgrade(): void {
|
|
74
|
+
try {
|
|
75
|
+
if (isLexicalBackfillComplete()) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (hasActiveJobOfType("backfill_lexical_index")) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const jobId = enqueueMemoryJob("backfill_lexical_index", {});
|
|
82
|
+
log.info(
|
|
83
|
+
{ jobId },
|
|
84
|
+
"Enqueued one-time messages lexical-index backfill on startup",
|
|
85
|
+
);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
log.warn(
|
|
88
|
+
{ err },
|
|
89
|
+
"Failed to enqueue startup lexical-index backfill (non-fatal)",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Messages indexed per job invocation before the job re-enqueues itself. */
|
|
95
|
+
const BATCH_SIZE = 200;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Resumable, cursor-checkpointed backfill of existing messages into the Qdrant
|
|
99
|
+
* lexical index. Selects the next {@link BATCH_SIZE} messages ordered by
|
|
100
|
+
* `(createdAt asc, id asc)` after the persisted cursor, encodes each with the
|
|
101
|
+
* local sparse encoder, batch-upserts them, advances the cursor, and
|
|
102
|
+
* re-enqueues itself when the batch is full — draining the whole `messages`
|
|
103
|
+
* table across many short invocations without blocking the event loop.
|
|
104
|
+
*
|
|
105
|
+
* Idempotent: the upsert keys on a deterministic point id derived from the
|
|
106
|
+
* message id, so re-indexing the same message overwrites the same point. Pass
|
|
107
|
+
* `payload.force` to reset the cursor and re-index from the beginning.
|
|
108
|
+
*/
|
|
109
|
+
export async function backfillLexicalIndexJob(
|
|
110
|
+
job: MemoryJob,
|
|
111
|
+
config: AssistantConfig,
|
|
112
|
+
): Promise<void> {
|
|
113
|
+
const db = getDb();
|
|
114
|
+
const force = job.payload.force === true;
|
|
115
|
+
if (force) {
|
|
116
|
+
resetMessageCursorCheckpoint(
|
|
117
|
+
LEXICAL_BACKFILL_CHECKPOINT_KEY,
|
|
118
|
+
LEXICAL_BACKFILL_CHECKPOINT_ID_KEY,
|
|
119
|
+
);
|
|
120
|
+
// Clearing the completion sentinel lets a forced re-run drain and re-mark
|
|
121
|
+
// as complete, and re-arms the one-time startup auto-enqueue for this run.
|
|
122
|
+
// The route also clears this at enqueue time (so reads fall back to FTS
|
|
123
|
+
// before the worker claims the job); clearing again here is idempotent and
|
|
124
|
+
// keeps the forced-run semantics self-contained in the handler.
|
|
125
|
+
clearLexicalBackfillComplete();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const cursor = readMessageCursorCheckpoint(
|
|
129
|
+
LEXICAL_BACKFILL_CHECKPOINT_KEY,
|
|
130
|
+
LEXICAL_BACKFILL_CHECKPOINT_ID_KEY,
|
|
131
|
+
);
|
|
132
|
+
const batch = db
|
|
133
|
+
.select({
|
|
134
|
+
id: messages.id,
|
|
135
|
+
conversationId: messages.conversationId,
|
|
136
|
+
content: messages.content,
|
|
137
|
+
createdAt: messages.createdAt,
|
|
138
|
+
})
|
|
139
|
+
.from(messages)
|
|
140
|
+
.where(
|
|
141
|
+
or(
|
|
142
|
+
gt(messages.createdAt, cursor.createdAt),
|
|
143
|
+
and(
|
|
144
|
+
eq(messages.createdAt, cursor.createdAt),
|
|
145
|
+
gt(messages.id, cursor.messageId),
|
|
146
|
+
),
|
|
147
|
+
),
|
|
148
|
+
)
|
|
149
|
+
.orderBy(asc(messages.createdAt), asc(messages.id))
|
|
150
|
+
.limit(BATCH_SIZE)
|
|
151
|
+
.all();
|
|
152
|
+
|
|
153
|
+
if (batch.length > 0) {
|
|
154
|
+
const index = resolveLexicalIndex(config);
|
|
155
|
+
const points = batch.map((message) => ({
|
|
156
|
+
messageId: message.id,
|
|
157
|
+
sparse: generateSparseEmbedding(message.content),
|
|
158
|
+
conversationId: message.conversationId,
|
|
159
|
+
createdAt: message.createdAt,
|
|
160
|
+
}));
|
|
161
|
+
await withQdrantBreaker(() => index.upsertMessagesBatch(points));
|
|
162
|
+
|
|
163
|
+
const lastMessage = batch[batch.length - 1];
|
|
164
|
+
writeMessageCursorCheckpoint(
|
|
165
|
+
LEXICAL_BACKFILL_CHECKPOINT_KEY,
|
|
166
|
+
LEXICAL_BACKFILL_CHECKPOINT_ID_KEY,
|
|
167
|
+
{
|
|
168
|
+
createdAt: lastMessage.createdAt,
|
|
169
|
+
messageId: lastMessage.id,
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// A full batch means there may be more rows past the new cursor — re-enqueue
|
|
175
|
+
// to continue draining. Never carry `force` forward: the reset already
|
|
176
|
+
// happened this invocation, and re-resetting would loop over the same head.
|
|
177
|
+
if (batch.length === BATCH_SIZE) {
|
|
178
|
+
enqueueMemoryJob("backfill_lexical_index", {});
|
|
179
|
+
} else {
|
|
180
|
+
// A short batch (including an empty one) means the cursor has reached the
|
|
181
|
+
// end of the `messages` table — the backfill has fully drained. Record the
|
|
182
|
+
// completion sentinel so the one-time startup auto-enqueue never schedules
|
|
183
|
+
// it again on this instance. Idempotent: re-running after completion draws
|
|
184
|
+
// an empty batch and simply re-sets the same marker.
|
|
185
|
+
setMemoryCheckpoint(LEXICAL_BACKFILL_COMPLETE_KEY, "1");
|
|
186
|
+
}
|
|
187
|
+
}
|