@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,251 @@
|
|
|
1
|
+
import { eq } from "drizzle-orm";
|
|
2
|
+
|
|
3
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
4
|
+
import { getLogger } from "../../util/logger.js";
|
|
5
|
+
import { getDb } from "../db-connection.js";
|
|
6
|
+
import { generateSparseEmbedding } from "../embeddings/embedding-backend.js";
|
|
7
|
+
import {
|
|
8
|
+
getMessagesLexicalIndex,
|
|
9
|
+
initMessagesLexicalIndex,
|
|
10
|
+
MESSAGES_LEXICAL_COLLECTION,
|
|
11
|
+
type MessagesLexicalIndex,
|
|
12
|
+
} from "../embeddings/messages-lexical-index.js";
|
|
13
|
+
import { withQdrantBreaker } from "../embeddings/qdrant-circuit-breaker.js";
|
|
14
|
+
import { resolveQdrantUrl } from "../embeddings/qdrant-client.js";
|
|
15
|
+
import { asString } from "../job-utils.js";
|
|
16
|
+
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
17
|
+
import { messages } from "../schema/index.js";
|
|
18
|
+
|
|
19
|
+
const log = getLogger("messages-lexical-enqueue");
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the messages lexical index singleton, lazily initializing it from
|
|
23
|
+
* `config` when it has not been set up in this process. The eager init in
|
|
24
|
+
* `runMemoryStartup` (startup.ts) only runs in the daemon process; the memory
|
|
25
|
+
* job worker can run as a separate OS process (`jobs/worker.ts`) that never
|
|
26
|
+
* calls `runMemoryStartup`, so without this fallback every lexical job claimed
|
|
27
|
+
* there would throw. `initMessagesLexicalIndex` is idempotent — it just
|
|
28
|
+
* (re)points the singleton at an equivalent client — so re-initializing from
|
|
29
|
+
* the same config is safe.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveLexicalIndex(
|
|
32
|
+
config: AssistantConfig,
|
|
33
|
+
): MessagesLexicalIndex {
|
|
34
|
+
try {
|
|
35
|
+
return getMessagesLexicalIndex();
|
|
36
|
+
} catch {
|
|
37
|
+
return initMessagesLexicalIndex({
|
|
38
|
+
url: resolveQdrantUrl(config),
|
|
39
|
+
collection: MESSAGES_LEXICAL_COLLECTION,
|
|
40
|
+
onDisk: config.memory.qdrant.onDisk,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Encode `message.content` with the local sparse encoder and upsert it into the
|
|
47
|
+
* messages lexical (Qdrant) index. The single shared indexing primitive — the
|
|
48
|
+
* `index_message_lexical` job and the backfill path both route through here so
|
|
49
|
+
* the encode + upsert sequence lives in one place.
|
|
50
|
+
*
|
|
51
|
+
* The upsert is wrapped in the Qdrant circuit breaker so a transient Qdrant
|
|
52
|
+
* outage trips the breaker and surfaces as a deferrable error rather than an
|
|
53
|
+
* unhandled throw; the job worker's retry/defer logic then drains the backlog
|
|
54
|
+
* once Qdrant recovers.
|
|
55
|
+
*/
|
|
56
|
+
export async function indexMessageToLexical(
|
|
57
|
+
message: {
|
|
58
|
+
id: string;
|
|
59
|
+
conversationId: string;
|
|
60
|
+
content: string;
|
|
61
|
+
createdAt: number;
|
|
62
|
+
},
|
|
63
|
+
config: AssistantConfig,
|
|
64
|
+
): Promise<void> {
|
|
65
|
+
const index = resolveLexicalIndex(config);
|
|
66
|
+
const sparse = generateSparseEmbedding(message.content);
|
|
67
|
+
await withQdrantBreaker(() =>
|
|
68
|
+
index.upsertMessage(message.id, sparse, {
|
|
69
|
+
conversationId: message.conversationId,
|
|
70
|
+
createdAt: message.createdAt,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function indexMessageLexicalJob(
|
|
76
|
+
job: MemoryJob,
|
|
77
|
+
config: AssistantConfig,
|
|
78
|
+
): Promise<void> {
|
|
79
|
+
const messageId = asString(job.payload.messageId);
|
|
80
|
+
if (!messageId) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const db = getDb();
|
|
85
|
+
const row = db
|
|
86
|
+
.select({
|
|
87
|
+
id: messages.id,
|
|
88
|
+
conversationId: messages.conversationId,
|
|
89
|
+
content: messages.content,
|
|
90
|
+
createdAt: messages.createdAt,
|
|
91
|
+
})
|
|
92
|
+
.from(messages)
|
|
93
|
+
.where(eq(messages.id, messageId))
|
|
94
|
+
.get();
|
|
95
|
+
|
|
96
|
+
// The message may have been deleted between enqueue and dispatch — no-op.
|
|
97
|
+
if (!row) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
await indexMessageToLexical(row, config);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Delete a conversation's points from the lexical index (the
|
|
106
|
+
* `purge_conversation_lexical` job body).
|
|
107
|
+
*/
|
|
108
|
+
async function purgeConversationLexical(
|
|
109
|
+
conversationId: string,
|
|
110
|
+
config: AssistantConfig,
|
|
111
|
+
): Promise<void> {
|
|
112
|
+
const index = resolveLexicalIndex(config);
|
|
113
|
+
await withQdrantBreaker(() => index.deleteByConversation(conversationId));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Delete a single message's point from the lexical index (the
|
|
118
|
+
* `delete_message_lexical` job body).
|
|
119
|
+
*/
|
|
120
|
+
async function deleteMessageLexical(
|
|
121
|
+
messageId: string,
|
|
122
|
+
config: AssistantConfig,
|
|
123
|
+
): Promise<void> {
|
|
124
|
+
const index = resolveLexicalIndex(config);
|
|
125
|
+
await withQdrantBreaker(() => index.deleteByMessageId(messageId));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function purgeConversationLexicalJob(
|
|
129
|
+
job: MemoryJob,
|
|
130
|
+
config: AssistantConfig,
|
|
131
|
+
): Promise<void> {
|
|
132
|
+
const conversationId = asString(job.payload.conversationId);
|
|
133
|
+
if (!conversationId) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
await purgeConversationLexical(conversationId, config);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function deleteMessageLexicalJob(
|
|
140
|
+
job: MemoryJob,
|
|
141
|
+
config: AssistantConfig,
|
|
142
|
+
): Promise<void> {
|
|
143
|
+
const messageId = asString(job.payload.messageId);
|
|
144
|
+
if (!messageId) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
await deleteMessageLexical(messageId, config);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Enqueue an `index_message_lexical` job for a single message so its content is
|
|
152
|
+
* (re)indexed into the lexical (Qdrant) index off the SQLite write path. Called
|
|
153
|
+
* wherever a message's content becomes durable — on persist and on the
|
|
154
|
+
* streaming/import finalize seams that mirror the segment indexer
|
|
155
|
+
* (`indexMessageNow`).
|
|
156
|
+
*
|
|
157
|
+
* One job per message (not a debounced per-conversation coalesce): the payload
|
|
158
|
+
* carries a specific `messageId`, so coalescing bursts by conversation would
|
|
159
|
+
* drop every message but the last from the index. The upsert into Qdrant is
|
|
160
|
+
* idempotent, so re-enqueuing the same message id is harmless.
|
|
161
|
+
*
|
|
162
|
+
* Unconditional: message-content search is host infrastructure, so indexing
|
|
163
|
+
* runs regardless of the memory feature's or memory plugin's state (the job
|
|
164
|
+
* worker drains the lexical types even while memory is disabled).
|
|
165
|
+
*
|
|
166
|
+
* Best-effort: the enqueue is a search side effect off the message write path,
|
|
167
|
+
* so a failure (e.g. the jobs database is unavailable) is swallowed and logged
|
|
168
|
+
* rather than propagated — an indexing hiccup must not escalate a successful
|
|
169
|
+
* message persist into a throw, mirroring the `indexMessageNow` call sites
|
|
170
|
+
* this runs beside.
|
|
171
|
+
*/
|
|
172
|
+
export function enqueueLexicalIndexForMessage(messageId: string): void {
|
|
173
|
+
if (!messageId) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
enqueueMemoryJob("index_message_lexical", { messageId });
|
|
178
|
+
} catch (err) {
|
|
179
|
+
log.warn(
|
|
180
|
+
{ err, messageId },
|
|
181
|
+
"Failed to enqueue lexical index job for message (non-fatal)",
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Purge a deleted/wiped conversation's points from the lexical index, as a
|
|
188
|
+
* `purge_conversation_lexical` job processed off the write path (the worker
|
|
189
|
+
* drains the lexical types regardless of the memory feature's state).
|
|
190
|
+
*
|
|
191
|
+
* The purge targets Qdrant by `conversationId`, so it is correct even after the
|
|
192
|
+
* conversation's message rows have been deleted. Callers on the wipe path must
|
|
193
|
+
* invoke this AFTER `cancelPendingJobsForConversation`, which fails every
|
|
194
|
+
* pending `conversationId`-keyed job — otherwise an enqueued purge is swept by
|
|
195
|
+
* that same cancellation.
|
|
196
|
+
*
|
|
197
|
+
* Best-effort: a failed enqueue is swallowed and logged rather than
|
|
198
|
+
* propagated, so conversation deletion never fails on an indexing hiccup.
|
|
199
|
+
*/
|
|
200
|
+
export function enqueuePurgeConversationLexical(conversationId: string): void {
|
|
201
|
+
if (!conversationId) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
enqueueMemoryJob("purge_conversation_lexical", { conversationId });
|
|
206
|
+
} catch (err) {
|
|
207
|
+
log.warn(
|
|
208
|
+
{ err, conversationId },
|
|
209
|
+
"Failed to schedule lexical purge for conversation (non-fatal)",
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Remove a deleted message's point from the lexical index, as a
|
|
216
|
+
* `delete_message_lexical` job. Used by single-message delete paths
|
|
217
|
+
* (consolidation, undo) that remove a row without wiping the whole
|
|
218
|
+
* conversation. Best-effort so message deletion never fails on an indexing
|
|
219
|
+
* hiccup.
|
|
220
|
+
*/
|
|
221
|
+
export function enqueueDeleteMessageLexical(messageId: string): void {
|
|
222
|
+
if (!messageId) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
enqueueMemoryJob("delete_message_lexical", { messageId });
|
|
227
|
+
} catch (err) {
|
|
228
|
+
log.warn(
|
|
229
|
+
{ err, messageId },
|
|
230
|
+
"Failed to schedule lexical delete for message (non-fatal)",
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Drop every point from the messages lexical index. Called inline (not via a
|
|
237
|
+
* job) by "clear all conversations": that path deletes all rows and the
|
|
238
|
+
* `memory_jobs` table itself, so there is nothing left to key a per-conversation
|
|
239
|
+
* purge job on. Best-effort — a Qdrant failure is swallowed, matching the other
|
|
240
|
+
* `clearAll` cleanup steps that tolerate failures.
|
|
241
|
+
*/
|
|
242
|
+
export async function clearMessagesLexicalIndex(
|
|
243
|
+
config: AssistantConfig,
|
|
244
|
+
): Promise<void> {
|
|
245
|
+
try {
|
|
246
|
+
const index = resolveLexicalIndex(config);
|
|
247
|
+
await withQdrantBreaker(() => index.clear());
|
|
248
|
+
} catch (err) {
|
|
249
|
+
log.warn({ err }, "Failed to clear messages lexical index (non-fatal)");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -36,6 +36,7 @@ export type MemoryJobType =
|
|
|
36
36
|
| "prune_old_conversations"
|
|
37
37
|
| "prune_old_llm_request_logs"
|
|
38
38
|
| "prune_old_trace_events"
|
|
39
|
+
| "prune_old_tool_invocations"
|
|
39
40
|
| "build_conversation_summary"
|
|
40
41
|
| "conversation_analyze"
|
|
41
42
|
| "backfill"
|
|
@@ -61,6 +62,10 @@ export type MemoryJobType =
|
|
|
61
62
|
| "memory_v2_reembed"
|
|
62
63
|
| "memory_v2_activation_recompute"
|
|
63
64
|
| "memory_v3_maintain"
|
|
65
|
+
| "index_message_lexical"
|
|
66
|
+
| "purge_conversation_lexical"
|
|
67
|
+
| "delete_message_lexical"
|
|
68
|
+
| "backfill_lexical_index"
|
|
64
69
|
// Retired/legacy — no live handler; persisted rows drop via LEGACY_JOB_TYPES.
|
|
65
70
|
| "memory_v3_consolidate"
|
|
66
71
|
| "memory_v3_index_maintenance"
|
|
@@ -78,6 +83,19 @@ export const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
|
78
83
|
"embed_concept_page",
|
|
79
84
|
];
|
|
80
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Job types that power message-content lexical search — host infrastructure
|
|
88
|
+
* that shares the background job queue but is not a memory feature. The worker
|
|
89
|
+
* keeps draining exactly these types while memory is disabled, so message
|
|
90
|
+
* search stays indexed regardless of the memory feature's state.
|
|
91
|
+
*/
|
|
92
|
+
export const MESSAGE_LEXICAL_JOB_TYPES: MemoryJobType[] = [
|
|
93
|
+
"index_message_lexical",
|
|
94
|
+
"purge_conversation_lexical",
|
|
95
|
+
"delete_message_lexical",
|
|
96
|
+
"backfill_lexical_index",
|
|
97
|
+
];
|
|
98
|
+
|
|
81
99
|
export const SLOW_LLM_JOB_TYPES: MemoryJobType[] = [
|
|
82
100
|
"graph_consolidate",
|
|
83
101
|
"graph_pattern_scan",
|
|
@@ -501,20 +519,84 @@ export function enqueuePruneOldTraceEventsJob(retentionDays?: number): string {
|
|
|
501
519
|
return enqueueMemoryJob("prune_old_trace_events", payload);
|
|
502
520
|
}
|
|
503
521
|
|
|
522
|
+
export function enqueuePruneOldToolInvocationsJob(
|
|
523
|
+
retentionDays?: number,
|
|
524
|
+
): string {
|
|
525
|
+
const db = memoryDb();
|
|
526
|
+
const existing = db
|
|
527
|
+
.select()
|
|
528
|
+
.from(memoryJobs)
|
|
529
|
+
.where(
|
|
530
|
+
and(
|
|
531
|
+
eq(memoryJobs.type, "prune_old_tool_invocations"),
|
|
532
|
+
inArray(memoryJobs.status, ["pending", "running"]),
|
|
533
|
+
),
|
|
534
|
+
)
|
|
535
|
+
.orderBy(asc(memoryJobs.createdAt))
|
|
536
|
+
.get();
|
|
537
|
+
if (existing) {
|
|
538
|
+
if (
|
|
539
|
+
existing.status === "pending" &&
|
|
540
|
+
typeof retentionDays === "number" &&
|
|
541
|
+
Number.isFinite(retentionDays) &&
|
|
542
|
+
retentionDays >= 0
|
|
543
|
+
) {
|
|
544
|
+
let payload: Record<string, unknown> = {};
|
|
545
|
+
try {
|
|
546
|
+
payload = JSON.parse(existing.payload) as Record<string, unknown>;
|
|
547
|
+
} catch {
|
|
548
|
+
payload = {};
|
|
549
|
+
}
|
|
550
|
+
if (payload.retentionDays !== retentionDays) {
|
|
551
|
+
db.update(memoryJobs)
|
|
552
|
+
.set({
|
|
553
|
+
payload: JSON.stringify({ ...payload, retentionDays }),
|
|
554
|
+
updatedAt: Date.now(),
|
|
555
|
+
})
|
|
556
|
+
.where(eq(memoryJobs.id, existing.id))
|
|
557
|
+
.run();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return existing.id;
|
|
561
|
+
}
|
|
562
|
+
const payload =
|
|
563
|
+
typeof retentionDays === "number" &&
|
|
564
|
+
Number.isFinite(retentionDays) &&
|
|
565
|
+
retentionDays >= 0
|
|
566
|
+
? { retentionDays }
|
|
567
|
+
: {};
|
|
568
|
+
return enqueueMemoryJob("prune_old_tool_invocations", payload);
|
|
569
|
+
}
|
|
570
|
+
|
|
504
571
|
export interface LaneBudgets {
|
|
505
572
|
slowLlm: number;
|
|
506
573
|
fast: number;
|
|
507
574
|
embed: number;
|
|
508
575
|
}
|
|
509
576
|
|
|
510
|
-
|
|
511
|
-
|
|
577
|
+
/**
|
|
578
|
+
* Claim up to the per-lane budgets of pending jobs. When `restrictToTypes` is
|
|
579
|
+
* provided, only jobs of those types are eligible in every lane — the worker
|
|
580
|
+
* uses this to drain exclusively the message-lexical types while memory is
|
|
581
|
+
* disabled.
|
|
582
|
+
*/
|
|
583
|
+
export function claimMemoryJobs(
|
|
584
|
+
limits: LaneBudgets,
|
|
585
|
+
restrictToTypes?: readonly MemoryJobType[],
|
|
586
|
+
): MemoryJob[] {
|
|
587
|
+
if (limits.slowLlm <= 0 && limits.fast <= 0 && limits.embed <= 0) {
|
|
588
|
+
return [];
|
|
589
|
+
}
|
|
512
590
|
|
|
513
591
|
const db = memoryDb();
|
|
514
592
|
const now = Date.now();
|
|
593
|
+
const restrictFilter = restrictToTypes
|
|
594
|
+
? inArray(memoryJobs.type, [...restrictToTypes])
|
|
595
|
+
: undefined;
|
|
515
596
|
const pendingFilter = and(
|
|
516
597
|
eq(memoryJobs.status, "pending"),
|
|
517
598
|
lte(memoryJobs.runAfter, now),
|
|
599
|
+
restrictFilter,
|
|
518
600
|
);
|
|
519
601
|
|
|
520
602
|
// Slow lane: long-running LLM jobs (graph extract/consolidate, analysis, etc.).
|
|
@@ -596,7 +678,9 @@ export function claimMemoryJobs(limits: LaneBudgets): MemoryJob[] {
|
|
|
596
678
|
.set({ status: "running", startedAt: now, updatedAt: now })
|
|
597
679
|
.where(and(eq(memoryJobs.id, row.id), eq(memoryJobs.status, "pending")))
|
|
598
680
|
.run();
|
|
599
|
-
if (rawMemoryChanges() === 0)
|
|
681
|
+
if (rawMemoryChanges() === 0) {
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
600
684
|
claimed.push(
|
|
601
685
|
parseRow({
|
|
602
686
|
...row,
|
|
@@ -640,7 +724,9 @@ const DEFER_MAX_DELAY_MS = 5 * 60 * 1000;
|
|
|
640
724
|
export function deferMemoryJob(id: string): "deferred" | "failed" {
|
|
641
725
|
const db = memoryDb();
|
|
642
726
|
const row = db.select().from(memoryJobs).where(eq(memoryJobs.id, id)).get();
|
|
643
|
-
if (!row)
|
|
727
|
+
if (!row) {
|
|
728
|
+
return "failed";
|
|
729
|
+
}
|
|
644
730
|
|
|
645
731
|
const deferrals = row.deferrals + 1;
|
|
646
732
|
const now = Date.now();
|
|
@@ -697,7 +783,9 @@ export function failMemoryJob(
|
|
|
697
783
|
const maxAttempts = options?.maxAttempts ?? 5;
|
|
698
784
|
const db = memoryDb();
|
|
699
785
|
const row = db.select().from(memoryJobs).where(eq(memoryJobs.id, id)).get();
|
|
700
|
-
if (!row)
|
|
786
|
+
if (!row) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
701
789
|
const attempts = row.attempts + 1;
|
|
702
790
|
const now = Date.now();
|
|
703
791
|
if (attempts >= maxAttempts) {
|
|
@@ -741,6 +829,7 @@ export function failStalledJobs(timeoutMs: number): number {
|
|
|
741
829
|
const now = Date.now();
|
|
742
830
|
const cutoff = now - timeoutMs;
|
|
743
831
|
const stalled = rawMemoryAll<{ id: string; type: string }>(
|
|
832
|
+
"jobs:failStalledJobs:select",
|
|
744
833
|
`
|
|
745
834
|
SELECT id, type
|
|
746
835
|
FROM memory_jobs
|
|
@@ -750,7 +839,9 @@ export function failStalledJobs(timeoutMs: number): number {
|
|
|
750
839
|
`,
|
|
751
840
|
cutoff,
|
|
752
841
|
);
|
|
753
|
-
if (stalled.length === 0)
|
|
842
|
+
if (stalled.length === 0) {
|
|
843
|
+
return 0;
|
|
844
|
+
}
|
|
754
845
|
|
|
755
846
|
const db = memoryDb();
|
|
756
847
|
for (const row of stalled) {
|
|
@@ -773,11 +864,14 @@ export function failStalledJobs(timeoutMs: number): number {
|
|
|
773
864
|
}
|
|
774
865
|
|
|
775
866
|
export function getMemoryJobCounts(): Record<string, number> {
|
|
776
|
-
const rows = rawMemoryAll<{ status: string; c: number }>(
|
|
867
|
+
const rows = rawMemoryAll<{ status: string; c: number }>(
|
|
868
|
+
"jobs:getMemoryJobCounts",
|
|
869
|
+
`
|
|
777
870
|
SELECT status, COUNT(*) AS c
|
|
778
871
|
FROM memory_jobs
|
|
779
872
|
GROUP BY status
|
|
780
|
-
|
|
873
|
+
`,
|
|
874
|
+
);
|
|
781
875
|
const counts: Record<string, number> = {
|
|
782
876
|
pending: 0,
|
|
783
877
|
running: 0,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
|
|
3
1
|
import { getConfig } from "../config/loader.js";
|
|
4
2
|
import { isMemoryV3Live } from "../config/memory-v3-gate.js";
|
|
5
3
|
import type { AssistantConfig } from "../config/types.js";
|
|
@@ -8,9 +6,7 @@ import {
|
|
|
8
6
|
diskPressureBackgroundSkipLogFields,
|
|
9
7
|
shouldLogDiskPressureBackgroundSkip,
|
|
10
8
|
} from "../daemon/disk-pressure-background-gate.js";
|
|
11
|
-
import { countBufferLines } from "../plugins/defaults/memory/v2/consolidation-job.js";
|
|
12
9
|
import { getLogger } from "../util/logger.js";
|
|
13
|
-
import { getWorkspaceDir } from "../util/platform.js";
|
|
14
10
|
import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
|
|
15
11
|
import {
|
|
16
12
|
getLastScheduledCleanupEnqueueMs,
|
|
@@ -37,6 +33,7 @@ import {
|
|
|
37
33
|
enqueueMemoryJob,
|
|
38
34
|
enqueuePruneOldConversationsJob,
|
|
39
35
|
enqueuePruneOldLlmRequestLogsJob,
|
|
36
|
+
enqueuePruneOldToolInvocationsJob,
|
|
40
37
|
enqueuePruneOldTraceEventsJob,
|
|
41
38
|
failMemoryJob,
|
|
42
39
|
failStalledJobs,
|
|
@@ -44,6 +41,7 @@ import {
|
|
|
44
41
|
MEMORY_V2_CONSOLIDATION_JOB_TRIGGERS,
|
|
45
42
|
type MemoryJob,
|
|
46
43
|
type MemoryJobType,
|
|
44
|
+
MESSAGE_LEXICAL_JOB_TYPES,
|
|
47
45
|
resetRunningJobsToPending,
|
|
48
46
|
SLOW_LLM_JOB_TYPES,
|
|
49
47
|
} from "./jobs-store.js";
|
|
@@ -206,7 +204,9 @@ export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
|
206
204
|
* stopMemoryWorkerProcess() in worker-control.ts.
|
|
207
205
|
*/
|
|
208
206
|
export function stopMemoryJobsWorker(): void {
|
|
209
|
-
if (!instance)
|
|
207
|
+
if (!instance) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
210
|
instance.stop();
|
|
211
211
|
instance = null;
|
|
212
212
|
}
|
|
@@ -251,7 +251,9 @@ export function startInProcessMemoryJobsWorker(
|
|
|
251
251
|
let currentIntervalMs = POLL_INTERVAL_MIN_MS;
|
|
252
252
|
|
|
253
253
|
const tick = async () => {
|
|
254
|
-
if (stopped || tickRunning)
|
|
254
|
+
if (stopped || tickRunning) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
255
257
|
tickRunning = true;
|
|
256
258
|
try {
|
|
257
259
|
if (
|
|
@@ -296,17 +298,23 @@ export function startInProcessMemoryJobsWorker(
|
|
|
296
298
|
};
|
|
297
299
|
|
|
298
300
|
const scheduleTick = () => {
|
|
299
|
-
if (stopped)
|
|
301
|
+
if (stopped) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
300
304
|
timer = setTimeout(() => {
|
|
301
305
|
void tick().then(() => {
|
|
302
|
-
if (!stopped)
|
|
306
|
+
if (!stopped) {
|
|
307
|
+
scheduleTick();
|
|
308
|
+
}
|
|
303
309
|
});
|
|
304
310
|
}, currentIntervalMs);
|
|
305
311
|
(timer as NodeJS.Timeout).unref?.();
|
|
306
312
|
};
|
|
307
313
|
|
|
308
314
|
void tick().then(() => {
|
|
309
|
-
if (!stopped)
|
|
315
|
+
if (!stopped) {
|
|
316
|
+
scheduleTick();
|
|
317
|
+
}
|
|
310
318
|
});
|
|
311
319
|
|
|
312
320
|
return {
|
|
@@ -326,8 +334,13 @@ export async function runMemoryJobsOnce(
|
|
|
326
334
|
options: { enableScheduledCleanup?: boolean } = {},
|
|
327
335
|
): Promise<number> {
|
|
328
336
|
const config = getConfig();
|
|
329
|
-
|
|
330
|
-
|
|
337
|
+
// While memory is disabled the queue still drains the MESSAGE-LEXICAL job
|
|
338
|
+
// types — host-owned message-search indexing that shares this queue but is
|
|
339
|
+
// not a memory feature. Every memory lane and every maintenance enqueue
|
|
340
|
+
// stays idle in that state; only the lexical types are claimable.
|
|
341
|
+
const memoryEnabled = config.memory.enabled !== false;
|
|
342
|
+
const enableScheduledCleanup =
|
|
343
|
+
options.enableScheduledCleanup === true && memoryEnabled;
|
|
331
344
|
|
|
332
345
|
const diskPressureGate = checkDiskPressureBackgroundGate("background-work");
|
|
333
346
|
if (diskPressureGate.action === "skip") {
|
|
@@ -355,19 +368,26 @@ export async function runMemoryJobsOnce(
|
|
|
355
368
|
|
|
356
369
|
// Claim per-lane budgets so a backlog of slow LLM jobs cannot starve fast
|
|
357
370
|
// jobs (and vice versa). The Qdrant circuit breaker still gates only the
|
|
358
|
-
// embed lane inside `claimMemoryJobs`.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
371
|
+
// embed lane inside `claimMemoryJobs`. With memory disabled, the slow and
|
|
372
|
+
// embed lanes get no budget and the fast lane is restricted to the
|
|
373
|
+
// message-lexical types (they ride the fast lane).
|
|
374
|
+
const claimed = claimMemoryJobs(
|
|
375
|
+
{
|
|
376
|
+
slowLlm: memoryEnabled ? cfgSlow : 0,
|
|
377
|
+
fast: cfgFast,
|
|
378
|
+
embed: memoryEnabled ? cfgEmbed : 0,
|
|
379
|
+
},
|
|
380
|
+
memoryEnabled ? undefined : MESSAGE_LEXICAL_JOB_TYPES,
|
|
381
|
+
);
|
|
364
382
|
|
|
365
383
|
if (claimed.length === 0) {
|
|
366
384
|
if (enableScheduledCleanup) {
|
|
367
385
|
maybeEnqueueScheduledCleanupJobs(config);
|
|
368
386
|
}
|
|
369
387
|
maybeEnqueueGraphMaintenanceJobs(config);
|
|
370
|
-
|
|
388
|
+
if (memoryEnabled) {
|
|
389
|
+
await maybeRunDbMaintenance();
|
|
390
|
+
}
|
|
371
391
|
return 0;
|
|
372
392
|
}
|
|
373
393
|
|
|
@@ -451,7 +471,9 @@ async function runLanePool(
|
|
|
451
471
|
concurrency: number,
|
|
452
472
|
processGroup: ProcessGroup,
|
|
453
473
|
): Promise<number> {
|
|
454
|
-
if (jobs.length === 0)
|
|
474
|
+
if (jobs.length === 0) {
|
|
475
|
+
return 0;
|
|
476
|
+
}
|
|
455
477
|
|
|
456
478
|
const groups = new Map<string, MemoryJob[]>();
|
|
457
479
|
for (const job of jobs) {
|
|
@@ -490,7 +512,9 @@ async function runLanePool(
|
|
|
490
512
|
// starts the instant any slot frees up.
|
|
491
513
|
let nextIdx = 0;
|
|
492
514
|
const startNext = (): Promise<void> | undefined => {
|
|
493
|
-
if (nextIdx >= typeGroups.length)
|
|
515
|
+
if (nextIdx >= typeGroups.length) {
|
|
516
|
+
return undefined;
|
|
517
|
+
}
|
|
494
518
|
const group = typeGroups[nextIdx++]!;
|
|
495
519
|
return processGroup(group)
|
|
496
520
|
.then(
|
|
@@ -634,9 +658,12 @@ function maybeEnqueueScheduledCleanupJobs(
|
|
|
634
658
|
nowMs = Date.now(),
|
|
635
659
|
): boolean {
|
|
636
660
|
const cleanup = config.memory.cleanup;
|
|
637
|
-
if (!cleanup.enabled)
|
|
638
|
-
if (nowMs - getLastScheduledCleanupEnqueueMs() < cleanup.enqueueIntervalMs)
|
|
661
|
+
if (!cleanup.enabled) {
|
|
639
662
|
return false;
|
|
663
|
+
}
|
|
664
|
+
if (nowMs - getLastScheduledCleanupEnqueueMs() < cleanup.enqueueIntervalMs) {
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
640
667
|
|
|
641
668
|
const pruneConversationsJobId =
|
|
642
669
|
cleanup.conversationRetentionDays > 0
|
|
@@ -650,16 +677,24 @@ function maybeEnqueueScheduledCleanupJobs(
|
|
|
650
677
|
cleanup.traceEventRetentionDays > 0
|
|
651
678
|
? enqueuePruneOldTraceEventsJob(cleanup.traceEventRetentionDays)
|
|
652
679
|
: null;
|
|
680
|
+
// Audit-log (tool_invocations) retention is configured separately under
|
|
681
|
+
// `auditLog.retentionDays`, but rides this same cleanup cadence for now.
|
|
682
|
+
const pruneToolInvocationsJobId =
|
|
683
|
+
config.auditLog.retentionDays > 0
|
|
684
|
+
? enqueuePruneOldToolInvocationsJob(config.auditLog.retentionDays)
|
|
685
|
+
: null;
|
|
653
686
|
markScheduledCleanupEnqueued(nowMs);
|
|
654
687
|
log.debug(
|
|
655
688
|
{
|
|
656
689
|
pruneConversationsJobId,
|
|
657
690
|
pruneLlmRequestLogsJobId,
|
|
658
691
|
pruneTraceEventsJobId,
|
|
692
|
+
pruneToolInvocationsJobId,
|
|
659
693
|
enqueueIntervalMs: cleanup.enqueueIntervalMs,
|
|
660
694
|
conversationRetentionDays: cleanup.conversationRetentionDays,
|
|
661
695
|
llmRequestLogRetentionMs: cleanup.llmRequestLogRetentionMs,
|
|
662
696
|
traceEventRetentionDays: cleanup.traceEventRetentionDays,
|
|
697
|
+
auditLogRetentionDays: config.auditLog.retentionDays,
|
|
663
698
|
},
|
|
664
699
|
"Enqueued scheduled memory cleanup jobs",
|
|
665
700
|
);
|
|
@@ -721,7 +756,9 @@ export function maybeEnqueueGraphMaintenanceJobs(
|
|
|
721
756
|
nowMs = Date.now(),
|
|
722
757
|
): void {
|
|
723
758
|
const memoryEnabled = config.memory.enabled !== false;
|
|
724
|
-
if (!memoryEnabled)
|
|
759
|
+
if (!memoryEnabled) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
725
762
|
|
|
726
763
|
const v2Active = config.memory.v2.enabled;
|
|
727
764
|
|
|
@@ -787,8 +824,10 @@ export function maybeEnqueueGraphMaintenanceJobs(
|
|
|
787
824
|
// The checkpoint advances so the next check fires after the regular
|
|
788
825
|
// interval. Manual "Run now" is unaffected (routes layer, not schedule).
|
|
789
826
|
if (jobType === consolidateEntry.jobType) {
|
|
790
|
-
|
|
791
|
-
|
|
827
|
+
if (
|
|
828
|
+
getMemoryPersistenceHooks().countMemoryBufferLines() <
|
|
829
|
+
MIN_BUFFER_LINES_FOR_CONSOLIDATION
|
|
830
|
+
) {
|
|
792
831
|
log.debug(
|
|
793
832
|
"Scheduled consolidation skipped: buffer under minimum line threshold",
|
|
794
833
|
);
|
|
@@ -802,7 +841,9 @@ export function maybeEnqueueGraphMaintenanceJobs(
|
|
|
802
841
|
: {};
|
|
803
842
|
enqueueMemoryJob(jobType, payload);
|
|
804
843
|
setMemoryCheckpoint(key, String(nowMs));
|
|
805
|
-
if (jobType === consolidateEntry.jobType)
|
|
844
|
+
if (jobType === consolidateEntry.jobType) {
|
|
845
|
+
enqueuedConsolidate = true;
|
|
846
|
+
}
|
|
806
847
|
}
|
|
807
848
|
}
|
|
808
849
|
|
|
@@ -821,8 +862,7 @@ export function maybeEnqueueGraphMaintenanceJobs(
|
|
|
821
862
|
maxLines !== null &&
|
|
822
863
|
!hasActiveJobOfType(consolidateEntry.jobType)
|
|
823
864
|
) {
|
|
824
|
-
|
|
825
|
-
if (countBufferLines(bufferPath) >= maxLines) {
|
|
865
|
+
if (getMemoryPersistenceHooks().countMemoryBufferLines() >= maxLines) {
|
|
826
866
|
enqueueMemoryJob(
|
|
827
867
|
consolidateEntry.jobType,
|
|
828
868
|
AUTOMATIC_CONSOLIDATION_JOB_PAYLOAD,
|