@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
|
@@ -4,8 +4,8 @@ import type {
|
|
|
4
4
|
ProviderResponse,
|
|
5
5
|
ToolUseContent,
|
|
6
6
|
} from "@vellumai/plugin-api";
|
|
7
|
+
import { getConfiguredProvider } from "@vellumai/plugin-api";
|
|
7
8
|
|
|
8
|
-
import { getConfiguredProvider } from "../../../../providers/provider-send-message.js";
|
|
9
9
|
import { redactSecrets } from "../../../../security/secret-scanner.js";
|
|
10
10
|
import {
|
|
11
11
|
buildRecallAgentPromptBundle,
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { readSlackMetadata } from "../../../../../messaging/providers/slack/message-metadata.js";
|
|
2
2
|
import { AUTO_ANALYSIS_SOURCE } from "../../../../../persistence/auto-analysis-constants.js";
|
|
3
|
+
import { isLexicalBackfillComplete } from "../../../../../persistence/checkpoints.js";
|
|
3
4
|
import {
|
|
4
|
-
buildFtsMatchQuery,
|
|
5
5
|
buildRecallEvidenceExcerpt,
|
|
6
|
+
hasLexicalTokens,
|
|
6
7
|
} from "../../../../../persistence/conversation-queries.js";
|
|
8
|
+
import { searchMessageIdsLexical } from "../../../../../persistence/conversation-search-lexical.js";
|
|
7
9
|
import { rawAll } from "../../../../../persistence/raw-query.js";
|
|
8
10
|
import {
|
|
9
11
|
parseExternalContentEnvelope,
|
|
10
12
|
wrapUntrustedContent,
|
|
11
13
|
} from "../../../../../security/untrusted-content.js";
|
|
14
|
+
import { getLogger } from "../../../../../util/logger.js";
|
|
12
15
|
import type { RecallSearchContext, RecallSearchResult } from "../types.js";
|
|
13
16
|
|
|
17
|
+
const log = getLogger("recall-conversations-source");
|
|
18
|
+
|
|
14
19
|
const SUBAGENT_SOURCE = "subagent";
|
|
15
20
|
const NOTIFICATION_SOURCE = "notification";
|
|
16
21
|
|
|
@@ -24,7 +29,30 @@ interface ConversationEvidenceRow {
|
|
|
24
29
|
title: string | null;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Qdrant candidate over-fetch multiplier for the lexical read path.
|
|
34
|
+
*
|
|
35
|
+
* The read fetches ranked message-id candidates first and filters them in SQL
|
|
36
|
+
* afterwards (Qdrant has no visibility filtering), so it must over-fetch
|
|
37
|
+
* enough candidates that excluded rows (the active conversation,
|
|
38
|
+
* subagent/auto-analysis/notification sources, private history) don't starve
|
|
39
|
+
* the post-filter pool. A generous candidate pool is cheap — the final
|
|
40
|
+
* consumer takes top-N after the app-side scorer anyway.
|
|
41
|
+
*
|
|
42
|
+
* This is a proportionate over-fetch, NOT a hard guarantee: a query whose
|
|
43
|
+
* visible matches all rank beyond the widened window can still be
|
|
44
|
+
* under-filled. A stronger fix would need pagination or Qdrant group-search.
|
|
45
|
+
*/
|
|
46
|
+
const QDRANT_RECALL_CANDIDATE_MULTIPLIER = 20;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Floor for the Qdrant candidate pool, so small `max_results` requests still
|
|
50
|
+
* over-fetch a healthy number of candidates before SQL filtering. Recall's
|
|
51
|
+
* `max_results` is capped at `MAX_RECALL_MAX_RESULTS` (20), so the pool is
|
|
52
|
+
* bounded at 20 × 20 = 400 candidate ids — far under the SQLite bound-variable
|
|
53
|
+
* limit (32766), so the `WHERE m.id IN (...)` query needs no chunking.
|
|
54
|
+
*/
|
|
55
|
+
const QDRANT_RECALL_MIN_CANDIDATES = 200;
|
|
28
56
|
|
|
29
57
|
const NON_SALIENT_RECALL_TERMS = new Set([
|
|
30
58
|
"a",
|
|
@@ -86,30 +114,42 @@ export async function searchConversationSource(
|
|
|
86
114
|
return { evidence: [] };
|
|
87
115
|
}
|
|
88
116
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
rows = mergeConversationRows(
|
|
99
|
-
rows,
|
|
100
|
-
searchWithFts(ftsMatch, queryLimit, context.conversationId),
|
|
101
|
-
);
|
|
102
|
-
} catch {
|
|
103
|
-
// Try the next, broader query shape.
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (rows.length >= normalizedLimit) break;
|
|
117
|
+
// The Qdrant lexical index — the only source of conversation evidence — is
|
|
118
|
+
// populated unconditionally (host-owned message-search indexing), but until
|
|
119
|
+
// the one-time upgrade backfill has fully drained it holds only messages
|
|
120
|
+
// written since the write path went live. A qdrant read then would silently
|
|
121
|
+
// miss older content (an empty candidate set, not a throw), so the source
|
|
122
|
+
// yields no evidence instead of serving misleading partial results. The
|
|
123
|
+
// completion checkpoint is shared with the persistence read site.
|
|
124
|
+
if (!isLexicalBackfillComplete()) {
|
|
125
|
+
return { evidence: [] };
|
|
107
126
|
}
|
|
108
127
|
|
|
109
|
-
|
|
110
|
-
|
|
128
|
+
// Short/punctuation-only queries (`C++`, CJK) produce no usable ≥2-char
|
|
129
|
+
// token. Content matching is index-only, so such queries yield no
|
|
130
|
+
// conversation evidence. The early return also keeps the sparse encoder
|
|
131
|
+
// honest: it still emits a 1-char token for these queries, so querying the
|
|
132
|
+
// index anyway would return noisy hits.
|
|
133
|
+
if (!hasLexicalTokens(trimmedQuery)) {
|
|
134
|
+
return { evidence: [] };
|
|
111
135
|
}
|
|
112
136
|
|
|
137
|
+
// A brief post-edit staleness window (an edited message whose re-index job
|
|
138
|
+
// has not yet run, or a just-deleted message still present as a point) is
|
|
139
|
+
// an ACCEPTED consequence of async indexing. Recall is fuzzy evidence
|
|
140
|
+
// re-ranked by the app-side scorer, and the wide candidate pool dilutes a
|
|
141
|
+
// single stale hit; we do not re-verify candidate content against the query
|
|
142
|
+
// (a substring re-check would wrongly drop valid stemmed matches).
|
|
143
|
+
const qdrantCandidateLimit = Math.max(
|
|
144
|
+
normalizedLimit * QDRANT_RECALL_CANDIDATE_MULTIPLIER,
|
|
145
|
+
QDRANT_RECALL_MIN_CANDIDATES,
|
|
146
|
+
);
|
|
147
|
+
const rows = await gatherCandidateRowsFromQdrant(
|
|
148
|
+
trimmedQuery,
|
|
149
|
+
qdrantCandidateLimit,
|
|
150
|
+
context.conversationId,
|
|
151
|
+
);
|
|
152
|
+
|
|
113
153
|
const sortedRows = rows
|
|
114
154
|
.map((row) => ({
|
|
115
155
|
row,
|
|
@@ -135,46 +175,61 @@ export async function searchConversationSource(
|
|
|
135
175
|
};
|
|
136
176
|
}
|
|
137
177
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Generate candidate rows via the Qdrant lexical index. Qdrant is
|
|
180
|
+
* candidate-generation only: it supplies over-fetched message-id candidates
|
|
181
|
+
* (ranked by sparse score) whose rows are then re-fetched with the
|
|
182
|
+
* source/type/excluded-conversation predicates applied in SQL
|
|
183
|
+
* ({@link searchByIds}). Final ordering stays with the app-side scorer.
|
|
184
|
+
*
|
|
185
|
+
* `candidateLimit` is the widened over-fetch count (see
|
|
186
|
+
* {@link QDRANT_RECALL_CANDIDATE_MULTIPLIER}) — it bounds both the Qdrant fetch
|
|
187
|
+
* and the post-filter SQL `LIMIT`, so surviving candidates aren't dropped
|
|
188
|
+
* before scoring. Filtering shrinks the pool but never grows it, so the final
|
|
189
|
+
* `LIMIT` is a no-op ceiling here; it exists only to bound the returned rows.
|
|
190
|
+
*
|
|
191
|
+
* Returns an empty array when the query tokenizes to no sparse terms (the
|
|
192
|
+
* lexical helper's empty guard) or when the Qdrant call throws (logged) — the
|
|
193
|
+
* source then yields no conversation evidence for the query.
|
|
194
|
+
*/
|
|
195
|
+
async function gatherCandidateRowsFromQdrant(
|
|
196
|
+
query: string,
|
|
197
|
+
candidateLimit: number,
|
|
141
198
|
excludedConversationId: string,
|
|
142
|
-
): ConversationEvidenceRow[] {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
ORDER BY bm25(messages_fts), m.created_at DESC
|
|
161
|
-
LIMIT ?
|
|
162
|
-
`,
|
|
163
|
-
ftsMatch,
|
|
164
|
-
SUBAGENT_SOURCE,
|
|
165
|
-
AUTO_ANALYSIS_SOURCE,
|
|
166
|
-
NOTIFICATION_SOURCE,
|
|
167
|
-
excludedConversationId,
|
|
168
|
-
limit,
|
|
169
|
-
);
|
|
199
|
+
): Promise<ConversationEvidenceRow[]> {
|
|
200
|
+
let candidates: Array<{ messageId: string }>;
|
|
201
|
+
try {
|
|
202
|
+
candidates = await searchMessageIdsLexical(query, candidateLimit);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
log.warn(
|
|
205
|
+
{ err, query: query.slice(0, 80) },
|
|
206
|
+
"recall conversations source: Qdrant lexical query failed — no conversation evidence for this query",
|
|
207
|
+
);
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const candidateIds = candidates.map((candidate) => candidate.messageId);
|
|
212
|
+
if (candidateIds.length === 0) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return searchByIds(candidateIds, candidateLimit, excludedConversationId);
|
|
170
217
|
}
|
|
171
218
|
|
|
172
|
-
|
|
173
|
-
|
|
219
|
+
/**
|
|
220
|
+
* Fetch evidence rows for an explicit set of candidate message ids, applying
|
|
221
|
+
* the source/type/excluded-conversation predicates in SQL (Qdrant has no
|
|
222
|
+
* visibility filtering). The app-side scorer determines final ordering, so
|
|
223
|
+
* the SQL tie-break falls back to recency.
|
|
224
|
+
*/
|
|
225
|
+
function searchByIds(
|
|
226
|
+
messageIds: readonly string[],
|
|
174
227
|
limit: number,
|
|
175
228
|
excludedConversationId: string,
|
|
176
229
|
): ConversationEvidenceRow[] {
|
|
230
|
+
const placeholders = messageIds.map(() => "?").join(", ");
|
|
177
231
|
return rawAll<ConversationEvidenceRow>(
|
|
232
|
+
"convSearch:searchByIds",
|
|
178
233
|
`
|
|
179
234
|
SELECT
|
|
180
235
|
m.id AS message_id,
|
|
@@ -186,14 +241,14 @@ function searchWithLike(
|
|
|
186
241
|
c.title
|
|
187
242
|
FROM messages m
|
|
188
243
|
JOIN conversations c ON c.id = m.conversation_id
|
|
189
|
-
WHERE m.
|
|
244
|
+
WHERE m.id IN (${placeholders})
|
|
190
245
|
AND (c.source IS NULL OR c.source NOT IN (?, ?, ?))
|
|
191
246
|
AND c.id != ?
|
|
192
247
|
AND c.conversation_type != 'private'
|
|
193
248
|
ORDER BY m.created_at DESC
|
|
194
249
|
LIMIT ?
|
|
195
250
|
`,
|
|
196
|
-
|
|
251
|
+
...messageIds,
|
|
197
252
|
SUBAGENT_SOURCE,
|
|
198
253
|
AUTO_ANALYSIS_SOURCE,
|
|
199
254
|
NOTIFICATION_SOURCE,
|
|
@@ -228,7 +283,9 @@ function parseSlackRecallMetadata(rawMetadata: string | null): {
|
|
|
228
283
|
displayName?: string;
|
|
229
284
|
provenanceTrustClass?: string;
|
|
230
285
|
} | null {
|
|
231
|
-
if (!rawMetadata)
|
|
286
|
+
if (!rawMetadata) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
232
289
|
|
|
233
290
|
let parsed: unknown;
|
|
234
291
|
try {
|
|
@@ -242,9 +299,13 @@ function parseSlackRecallMetadata(rawMetadata: string | null): {
|
|
|
242
299
|
}
|
|
243
300
|
|
|
244
301
|
const metadata = parsed as Record<string, unknown>;
|
|
245
|
-
if (typeof metadata.slackMeta !== "string")
|
|
302
|
+
if (typeof metadata.slackMeta !== "string") {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
246
305
|
const slackMeta = readSlackMetadata(metadata.slackMeta);
|
|
247
|
-
if (!slackMeta)
|
|
306
|
+
if (!slackMeta) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
248
309
|
|
|
249
310
|
return {
|
|
250
311
|
...(slackMeta.displayName ? { displayName: slackMeta.displayName } : {}),
|
|
@@ -254,35 +315,6 @@ function parseSlackRecallMetadata(rawMetadata: string | null): {
|
|
|
254
315
|
};
|
|
255
316
|
}
|
|
256
317
|
|
|
257
|
-
function buildRecallFtsMatchQueries(query: string): string[] {
|
|
258
|
-
const queries: string[] = [];
|
|
259
|
-
const exact = buildFtsMatchQuery(query);
|
|
260
|
-
if (exact) {
|
|
261
|
-
queries.push(exact);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const salientTerms = tokenizeSalientRecallTerms(query);
|
|
265
|
-
if (salientTerms.length > 0) {
|
|
266
|
-
const salientAnd = salientTerms.map(quoteFtsToken).join(" ");
|
|
267
|
-
if (salientAnd && !queries.includes(salientAnd)) {
|
|
268
|
-
queries.push(salientAnd);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (salientTerms.length > 1) {
|
|
272
|
-
const salientOr = salientTerms.map(quoteFtsToken).join(" OR ");
|
|
273
|
-
if (!queries.includes(salientOr)) {
|
|
274
|
-
queries.push(salientOr);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return queries;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function quoteFtsToken(token: string): string {
|
|
283
|
-
return `"${token.replace(/"/g, '""')}"`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
318
|
function tokenizeSalientRecallTerms(text: string): string[] {
|
|
287
319
|
const terms = (text.toLowerCase().match(/[a-z0-9_]+/g) ?? []).filter(
|
|
288
320
|
(term) => term.length >= 2 && !NON_SALIENT_RECALL_TERMS.has(term),
|
|
@@ -290,22 +322,6 @@ function tokenizeSalientRecallTerms(text: string): string[] {
|
|
|
290
322
|
return [...new Set(terms)].slice(0, 12);
|
|
291
323
|
}
|
|
292
324
|
|
|
293
|
-
function mergeConversationRows(
|
|
294
|
-
existing: readonly ConversationEvidenceRow[],
|
|
295
|
-
next: readonly ConversationEvidenceRow[],
|
|
296
|
-
): ConversationEvidenceRow[] {
|
|
297
|
-
const seen = new Set(existing.map((row) => row.message_id));
|
|
298
|
-
const merged = [...existing];
|
|
299
|
-
for (const row of next) {
|
|
300
|
-
if (seen.has(row.message_id)) {
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
seen.add(row.message_id);
|
|
304
|
-
merged.push(row);
|
|
305
|
-
}
|
|
306
|
-
return merged;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
325
|
function scoreConversationRow(
|
|
310
326
|
row: ConversationEvidenceRow,
|
|
311
327
|
query: string,
|
|
@@ -329,13 +345,8 @@ function compareScoredConversationRows(
|
|
|
329
345
|
b: { row: ConversationEvidenceRow; score: number },
|
|
330
346
|
): number {
|
|
331
347
|
const scoreCompare = b.score - a.score;
|
|
332
|
-
if (scoreCompare !== 0)
|
|
348
|
+
if (scoreCompare !== 0) {
|
|
349
|
+
return scoreCompare;
|
|
350
|
+
}
|
|
333
351
|
return b.row.created_at - a.row.created_at;
|
|
334
352
|
}
|
|
335
|
-
|
|
336
|
-
function buildLikePattern(query: string): string {
|
|
337
|
-
return `%${query
|
|
338
|
-
.replace(/\\/g, "\\\\")
|
|
339
|
-
.replace(/%/g, "\\%")
|
|
340
|
-
.replace(/_/g, "\\_")}%`;
|
|
341
|
-
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { getConfig } from "../../../config/loader.js";
|
|
2
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
3
|
+
import type {
|
|
4
|
+
EmbeddingInput,
|
|
5
|
+
EmbeddingRequestOptions,
|
|
6
|
+
} from "../../../persistence/embeddings/embedding-types.js";
|
|
7
|
+
import { resolveQdrantUrl as resolveQdrantUrlWithConfig } from "../../../persistence/embeddings/qdrant-client.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Memory-internal accessor for the shared embeddings / vector subsystem.
|
|
11
|
+
*
|
|
12
|
+
* The embeddings operations live in `persistence/embeddings` (and
|
|
13
|
+
* `persistence/job-utils`) and take the full `AssistantConfig` as their first
|
|
14
|
+
* argument — they read both the `memory` slice (Qdrant collection and vector
|
|
15
|
+
* settings) and the `llm` slice (embedding-backend selection). Memory code
|
|
16
|
+
* reaches those operations through this accessor: the self-contained ones
|
|
17
|
+
* (`embedAndUpsert`, `selectedBackendSupportsMultimodal`, `resolveQdrantUrl`)
|
|
18
|
+
* resolve the live config internally, so their call sites need not hold it.
|
|
19
|
+
* `embedWithBackend` keeps its `config` parameter — it is a primitive whose
|
|
20
|
+
* vectors the caller stores alongside its own config-derived metadata (cache
|
|
21
|
+
* keys, vector-size checks, Qdrant collection), so it must embed with the
|
|
22
|
+
* caller's exact config snapshot rather than a re-read that could diverge from
|
|
23
|
+
* that metadata mid-operation.
|
|
24
|
+
*
|
|
25
|
+
* The embed operations are loaded via dynamic `import()` inside each wrapper so
|
|
26
|
+
* that importing this module for a single operation does not eagerly pull the
|
|
27
|
+
* whole embed/vector import graph (`job-utils`, `embedding-backend`) into the
|
|
28
|
+
* consumer. An eager pull would force every one of those modules' named exports
|
|
29
|
+
* to resolve at instantiation, which breaks the intentional partial module
|
|
30
|
+
* mocks in memory tests (a store that mocks only the exports it uses). Only the
|
|
31
|
+
* synchronous `resolveQdrantUrl` is imported statically.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
type EmbeddingTargetType = Parameters<
|
|
35
|
+
typeof import("../../../persistence/job-utils.js").embedAndUpsert
|
|
36
|
+
>[1];
|
|
37
|
+
|
|
38
|
+
/** Embed a target and upsert its vector to Qdrant. */
|
|
39
|
+
export async function embedAndUpsert(
|
|
40
|
+
targetType: EmbeddingTargetType,
|
|
41
|
+
targetId: string,
|
|
42
|
+
input: EmbeddingInput,
|
|
43
|
+
extraPayload?: Record<string, unknown>,
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
const { embedAndUpsert: withConfig } =
|
|
46
|
+
await import("../../../persistence/job-utils.js");
|
|
47
|
+
return withConfig(getConfig(), targetType, targetId, input, extraPayload);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Embed one or more inputs via the selected embedding backend. */
|
|
51
|
+
export async function embedWithBackend(
|
|
52
|
+
config: AssistantConfig,
|
|
53
|
+
inputs: EmbeddingInput[],
|
|
54
|
+
options?: EmbeddingRequestOptions,
|
|
55
|
+
): Promise<
|
|
56
|
+
Awaited<
|
|
57
|
+
ReturnType<
|
|
58
|
+
typeof import("../../../persistence/embeddings/embedding-backend.js").embedWithBackend
|
|
59
|
+
>
|
|
60
|
+
>
|
|
61
|
+
> {
|
|
62
|
+
const { embedWithBackend: withConfig } =
|
|
63
|
+
await import("../../../persistence/embeddings/embedding-backend.js");
|
|
64
|
+
return withConfig(config, inputs, options);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Whether the active embedding backend handles multimodal inputs. */
|
|
68
|
+
export async function selectedBackendSupportsMultimodal(): Promise<boolean> {
|
|
69
|
+
const { selectedBackendSupportsMultimodal: withConfig } =
|
|
70
|
+
await import("../../../persistence/embeddings/embedding-backend.js");
|
|
71
|
+
return withConfig(getConfig());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Resolve the Qdrant base URL for this process. */
|
|
75
|
+
export function resolveQdrantUrl(): string {
|
|
76
|
+
return resolveQdrantUrlWithConfig(getConfig());
|
|
77
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { and, desc, eq, inArray } from "drizzle-orm";
|
|
2
|
+
|
|
3
|
+
import { getDb } from "../../../persistence/db-connection.js";
|
|
4
|
+
import { conversations } from "../../../persistence/schema/index.js";
|
|
5
|
+
import { MEMORY_RETROSPECTIVE_SOURCES } from "./memory-retrospective-constants.js";
|
|
6
|
+
|
|
7
|
+
const MAX_FORK_CHAIN_DEPTH = 16;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Find the most recent memory-retrospective background conversation rooted
|
|
11
|
+
* at `parentConversationId`. Used by the memory-retrospective job handler
|
|
12
|
+
* to load the prior retrospective's `remember` calls into the new run's
|
|
13
|
+
* `<already_remembered>` block — bounded source-of-truth for "what the
|
|
14
|
+
* prior pass already saved" that scales as the source conversation grows.
|
|
15
|
+
*
|
|
16
|
+
* Walks up `forkParentConversationId` when no retrospective exists at the
|
|
17
|
+
* current level. This lets a forked conversation inherit dedup context from
|
|
18
|
+
* its source's most recent retro on the fork's *first* retrospective —
|
|
19
|
+
* otherwise the fork would re-save every fact the source already retro'd.
|
|
20
|
+
* Once the fork accumulates its own retros, those are found at the first
|
|
21
|
+
* iteration and we never walk up.
|
|
22
|
+
*
|
|
23
|
+
* The returned `forkParentConversationId` is the conversation the
|
|
24
|
+
* retrospective row is rooted at — `parentConversationId` itself when it has
|
|
25
|
+
* its own retros, or an ancestor when the chain walk found the row higher
|
|
26
|
+
* up. Callers that mutate the prior (e.g. GC of superseded runs) must check
|
|
27
|
+
* it against the source conversation: an ancestor's row is that ancestor's
|
|
28
|
+
* dedup baseline, not the caller's to delete.
|
|
29
|
+
*
|
|
30
|
+
* Returns `null` when no prior retrospective exists anywhere in the fork
|
|
31
|
+
* chain (true first-run case).
|
|
32
|
+
*
|
|
33
|
+
* Hits `idx_conversations_fork_parent_conversation_id` for the
|
|
34
|
+
* `forkParentConversationId` lookup.
|
|
35
|
+
*/
|
|
36
|
+
export function findMostRecentRetrospectiveFor(
|
|
37
|
+
parentConversationId: string,
|
|
38
|
+
): { id: string; forkParentConversationId: string } | null {
|
|
39
|
+
const db = getDb();
|
|
40
|
+
let currentId: string | null = parentConversationId;
|
|
41
|
+
for (let depth = 0; depth < MAX_FORK_CHAIN_DEPTH && currentId; depth++) {
|
|
42
|
+
const row = db
|
|
43
|
+
.select({ id: conversations.id })
|
|
44
|
+
.from(conversations)
|
|
45
|
+
.where(
|
|
46
|
+
and(
|
|
47
|
+
inArray(conversations.source, MEMORY_RETROSPECTIVE_SOURCES),
|
|
48
|
+
eq(conversations.forkParentConversationId, currentId),
|
|
49
|
+
),
|
|
50
|
+
)
|
|
51
|
+
.orderBy(desc(conversations.createdAt))
|
|
52
|
+
.limit(1)
|
|
53
|
+
.get();
|
|
54
|
+
if (row) return { id: row.id, forkParentConversationId: currentId };
|
|
55
|
+
|
|
56
|
+
const parent = db
|
|
57
|
+
.select({
|
|
58
|
+
forkParentConversationId: conversations.forkParentConversationId,
|
|
59
|
+
})
|
|
60
|
+
.from(conversations)
|
|
61
|
+
.where(eq(conversations.id, currentId))
|
|
62
|
+
.get();
|
|
63
|
+
currentId = parent?.forkParentConversationId ?? null;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter parsing for memory's concept-page and card `.md` files.
|
|
3
|
+
*
|
|
4
|
+
* Frontmatter is a YAML block delimited by `---` at the top of a file. Memory
|
|
5
|
+
* owns this parser rather than importing the host `skills/` copy so the plugin
|
|
6
|
+
* depends only on its own files, `@vellumai/plugin-api`, and external packages.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { parse as parseYaml } from "yaml";
|
|
10
|
+
|
|
11
|
+
import { getLogger } from "../../../util/logger.js";
|
|
12
|
+
|
|
13
|
+
const log = getLogger("memory-frontmatter");
|
|
14
|
+
|
|
15
|
+
/** Matches a `---` delimited frontmatter block at the start of a file. */
|
|
16
|
+
export const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
17
|
+
|
|
18
|
+
interface FrontmatterParseResult {
|
|
19
|
+
/** Key-value pairs extracted from the frontmatter block. */
|
|
20
|
+
fields: Record<string, unknown>;
|
|
21
|
+
/** The remaining file content after the frontmatter block. */
|
|
22
|
+
body: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse frontmatter fields from file content. Extracts key-value pairs from the
|
|
27
|
+
* `---` delimited block at the top of the file via a YAML parser, handling
|
|
28
|
+
* nested objects, arrays, quoted strings, and escape sequences natively.
|
|
29
|
+
* Returns `null` if no frontmatter block is found.
|
|
30
|
+
*/
|
|
31
|
+
export function parseFrontmatterFields(
|
|
32
|
+
content: string,
|
|
33
|
+
): FrontmatterParseResult | null {
|
|
34
|
+
const match = content.match(FRONTMATTER_REGEX);
|
|
35
|
+
if (!match) return null;
|
|
36
|
+
|
|
37
|
+
const frontmatter = match[1];
|
|
38
|
+
const body = content.slice(match[0].length);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const parsed = parseYaml(frontmatter);
|
|
42
|
+
if (parsed == null || typeof parsed !== "object") {
|
|
43
|
+
return { fields: {}, body };
|
|
44
|
+
}
|
|
45
|
+
return { fields: parsed as Record<string, unknown>, body };
|
|
46
|
+
} catch (err) {
|
|
47
|
+
log.warn({ err }, "Failed to parse YAML frontmatter");
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|