@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,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-statement duration logging for every `bun:sqlite` query — Drizzle and raw.
|
|
3
|
+
*
|
|
4
|
+
* `bun:sqlite` executes synchronously on the daemon's single event-loop thread,
|
|
5
|
+
* so any statement that runs long — a large history scan, a memory query, or a
|
|
6
|
+
* write that blocks on the WAL write-lock (`busy_timeout` makes a contended
|
|
7
|
+
* writer *wait*, spinning the loop for up to {@link SQLITE_BUSY_TIMEOUT_MS}) —
|
|
8
|
+
* freezes every other handler (SSE, HTTP, health) for its full duration. The
|
|
9
|
+
* event-loop watchdog can see *that* a freeze happened but not *what* ran, and
|
|
10
|
+
* the section-level {@link ./slow-sync-log timeSyncSection} only covers the few
|
|
11
|
+
* call sites that opt in — notably not the Drizzle ORM hot writers.
|
|
12
|
+
*
|
|
13
|
+
* {@link wrapSqliteForSlowQueryLogging} closes that gap by wrapping the three
|
|
14
|
+
* statement-execution entry points on a `Database` — `.query()`, `.prepare()`,
|
|
15
|
+
* and the `.run()` shortcut — so that every execution (`.run()/.get()/.all()/
|
|
16
|
+
* .values()`) is timed with `performance.now()`. Executions slower than
|
|
17
|
+
* {@link SLOW_QUERY_THRESHOLD_MS} are logged at WARN with the offending SQL,
|
|
18
|
+
* naming the specific query behind a freeze regardless of whether it came from
|
|
19
|
+
* Drizzle or {@link ./raw-query}.
|
|
20
|
+
*
|
|
21
|
+
* Attribution: raw-query callers attach a curated `.label()` (e.g.
|
|
22
|
+
* `"schedule:claimDue"`). Drizzle's fluent API has no chokepoint to label, so
|
|
23
|
+
* for any query without an explicit label the reporter derives a `caller` from
|
|
24
|
+
* the stack — `path:function:line` of the application frame that issued it —
|
|
25
|
+
* captured only on the slow path. Between the two, every slow query is
|
|
26
|
+
* attributable to its call site with no per-query annotation of Drizzle code.
|
|
27
|
+
*
|
|
28
|
+
* The same per-statement chokepoint also surfaces *failed* executions: when a
|
|
29
|
+
* statement throws, the error is handed to {@link observeSqliteStatementError}
|
|
30
|
+
* before it propagates unchanged. This is how the SQLite corruption watchdog
|
|
31
|
+
* notices `SQLITE_CORRUPT` / `SQLITE_NOTADB` on any query or write — read or
|
|
32
|
+
* write, Drizzle or raw — the moment the workload hits the damaged page.
|
|
33
|
+
*
|
|
34
|
+
* This is pure instrumentation: return values, parameter binding, transactions,
|
|
35
|
+
* savepoints, and error propagation are all preserved exactly. The fast path
|
|
36
|
+
* adds only a `performance.now()` pair and a numeric compare — no allocation,
|
|
37
|
+
* SQL slicing, or observer call happens unless the statement is slow or throws.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { basename } from "node:path";
|
|
41
|
+
import type { Database, Statement } from "bun:sqlite";
|
|
42
|
+
|
|
43
|
+
import { observeSqliteStatementError } from "../daemon/sqlite-corruption-watchdog.js";
|
|
44
|
+
import { getLogger } from "../util/logger.js";
|
|
45
|
+
|
|
46
|
+
const log = getLogger("slow-query");
|
|
47
|
+
|
|
48
|
+
// Parsed once at module load; falls back below for any non-positive or
|
|
49
|
+
// unparseable value.
|
|
50
|
+
const configuredThresholdMs = Number(
|
|
51
|
+
process.env.VELLUM_SLOW_QUERY_THRESHOLD_MS,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Statement executions that block the event loop at least this long are logged.
|
|
56
|
+
* Deliberately conservative (300ms) so it names sub-watchdog contributors
|
|
57
|
+
* without logging every fast query. Env-overridable for tuning on a busy host
|
|
58
|
+
* without a rebuild.
|
|
59
|
+
*/
|
|
60
|
+
export const SLOW_QUERY_THRESHOLD_MS =
|
|
61
|
+
Number.isFinite(configuredThresholdMs) && configuredThresholdMs > 0
|
|
62
|
+
? configuredThresholdMs
|
|
63
|
+
: 300;
|
|
64
|
+
|
|
65
|
+
/** Max SQL characters retained in the log preview. */
|
|
66
|
+
const SQL_PREVIEW_MAX = 120;
|
|
67
|
+
|
|
68
|
+
/** The statement methods that actually execute SQL and can block. */
|
|
69
|
+
const TIMED_METHODS = new Set(["run", "get", "all", "values"]);
|
|
70
|
+
|
|
71
|
+
/** A slow statement execution, as handed to {@link reportSlowQuery}. */
|
|
72
|
+
export interface SlowQueryEvent {
|
|
73
|
+
durationMs: number;
|
|
74
|
+
/** SQL preview (first {@link SQL_PREVIEW_MAX} chars). */
|
|
75
|
+
sql: string;
|
|
76
|
+
/** Number of rows returned, when the execution produced an array result. */
|
|
77
|
+
rowCount?: number;
|
|
78
|
+
/** Caller-supplied attribution tag, when the query was issued via `.label()`. */
|
|
79
|
+
label?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Auto-derived call site (`path:function:line`) for queries with no explicit
|
|
82
|
+
* `.label()` — notably every Drizzle query, which has no chokepoint to attach
|
|
83
|
+
* a label to. Captured from the stack only on the slow path.
|
|
84
|
+
*/
|
|
85
|
+
caller?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** This instrumentation module — never the query's call site. */
|
|
89
|
+
const SELF_MODULE = "slow-query-log.ts";
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Marks the assistant package's own source. In local-runtime installs the CLI
|
|
93
|
+
* runs the daemon from `<installDir>/node_modules/@vellumai/assistant/src/…`, so
|
|
94
|
+
* the assistant's own frames also contain `node_modules` — they must NOT be
|
|
95
|
+
* treated as third-party dependency frames when deriving the caller.
|
|
96
|
+
*/
|
|
97
|
+
const ASSISTANT_SRC_MARKER = "@vellumai/assistant/src/";
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* True for stack frames that are runtime/ORM/instrumentation plumbing rather
|
|
101
|
+
* than the application code that issued the query. Third-party dependency frames
|
|
102
|
+
* (Drizzle et al.) live under `node_modules/` or Bun's global install cache
|
|
103
|
+
* (`.bun/install/cache/drizzle-orm@x.y.z/…`) and are skipped — but the
|
|
104
|
+
* assistant's own packaged `src/` frames, which also live under `node_modules`,
|
|
105
|
+
* are preserved.
|
|
106
|
+
*/
|
|
107
|
+
function isPlumbingFrame(line: string): boolean {
|
|
108
|
+
// Runtime internals: `node:*` / `bun:*` modules and Bun's `native:` frames
|
|
109
|
+
// (moduleEvaluation, processTicksAndRejections, …).
|
|
110
|
+
if (
|
|
111
|
+
line.includes("node:") ||
|
|
112
|
+
line.includes("bun:") ||
|
|
113
|
+
line.includes("native:")
|
|
114
|
+
) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
if (line.includes(SELF_MODULE)) return true;
|
|
118
|
+
const isDependency =
|
|
119
|
+
line.includes("node_modules/") || line.includes(".bun/install/cache/");
|
|
120
|
+
return isDependency && !line.includes(ASSISTANT_SRC_MARKER);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** `src/`-relative path, or bare basename when the frame is outside `src/`. */
|
|
124
|
+
function shortenStackFile(file: string): string {
|
|
125
|
+
const idx = file.lastIndexOf("/src/");
|
|
126
|
+
if (idx >= 0) return file.slice(idx + "/src/".length);
|
|
127
|
+
return file.split("/").pop() ?? file;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Best-effort attribution for a query with no explicit label: the first stack
|
|
132
|
+
* frame outside this module, dependencies, and the runtime — i.e. the
|
|
133
|
+
* application code that issued the query. Returns e.g.
|
|
134
|
+
* `persistence/conversation-crud.ts:insertMessageCore:474`. Only called on the
|
|
135
|
+
* slow path (a query already past the threshold), so the `Error().stack` cost is
|
|
136
|
+
* incurred rarely. Accepts an explicit `stack` for testing.
|
|
137
|
+
*
|
|
138
|
+
* @internal exported only for unit tests.
|
|
139
|
+
*/
|
|
140
|
+
export function callerFromStack(
|
|
141
|
+
stack: string | undefined = new Error().stack,
|
|
142
|
+
): string | undefined {
|
|
143
|
+
if (!stack) return undefined;
|
|
144
|
+
const lines = stack.split("\n");
|
|
145
|
+
for (let i = 1; i < lines.length; i++) {
|
|
146
|
+
const line = lines[i];
|
|
147
|
+
if (!line.includes("at ")) continue;
|
|
148
|
+
if (isPlumbingFrame(line)) continue;
|
|
149
|
+
// Bun renders frames as `at fn (file:line:col)`, `at file:line:col`, or
|
|
150
|
+
// (for some optimized frames) `at file:line` with no function or column.
|
|
151
|
+
const withFn = line.match(
|
|
152
|
+
/at (?:async )?([^\s(]+) \((.+?):(\d+)(?::\d+)?\)/,
|
|
153
|
+
);
|
|
154
|
+
if (withFn) {
|
|
155
|
+
return `${shortenStackFile(withFn[2])}:${withFn[1]}:${withFn[3]}`;
|
|
156
|
+
}
|
|
157
|
+
const noFn = line.match(/at (?:async )?(.+?):(\d+)(?::\d+)?$/);
|
|
158
|
+
if (noFn) {
|
|
159
|
+
return `${shortenStackFile(noFn[1])}:${noFn[2]}`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Log a slow statement execution at WARN with its SQL and duration. */
|
|
166
|
+
export function reportSlowQuery(event: SlowQueryEvent): void {
|
|
167
|
+
log.warn(event, "Slow SQLite query blocked the event loop");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Context handed to {@link observeSqliteStatementError} for a failed execution. */
|
|
171
|
+
export interface StatementErrorContext {
|
|
172
|
+
/** SQL preview (first {@link SQL_PREVIEW_MAX} chars) of the failing statement. */
|
|
173
|
+
sql: string;
|
|
174
|
+
/**
|
|
175
|
+
* The database file's basename (e.g. `"assistant.db"` / `"assistant-logs.db"`),
|
|
176
|
+
* derived from the `Database`'s own `filename`. Always set by the wrapper;
|
|
177
|
+
* optional only for direct callers (tests) that construct a context by hand.
|
|
178
|
+
*/
|
|
179
|
+
database?: string;
|
|
180
|
+
/** Caller-supplied `.label()` attribution tag, when present. */
|
|
181
|
+
label?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Injectable seams so the wrapper is unit-testable with a fake clock/sink. */
|
|
185
|
+
export interface SlowQueryWatcherOptions {
|
|
186
|
+
thresholdMs?: number;
|
|
187
|
+
now?: () => number;
|
|
188
|
+
onSlowQuery?: (event: SlowQueryEvent) => void;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Fluent handle returned by {@link Database.label}; tags any slow-query log. */
|
|
192
|
+
export interface LabeledQueries {
|
|
193
|
+
query(sql: string, ...rest: unknown[]): Statement;
|
|
194
|
+
prepare(sql: string, ...rest: unknown[]): Statement;
|
|
195
|
+
run(sql: string, ...params: unknown[]): ReturnType<Database["run"]>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare module "bun:sqlite" {
|
|
199
|
+
interface Database {
|
|
200
|
+
/**
|
|
201
|
+
* Return `query`/`prepare`/`run` bound to `label`, so any slow-query log
|
|
202
|
+
* emitted for statements created through the returned handle carries it —
|
|
203
|
+
* e.g. `getSqlite().label("schedule::claimDue").query(sql).run(...)`.
|
|
204
|
+
* Only present on connections wrapped by
|
|
205
|
+
* {@link wrapSqliteForSlowQueryLogging} (all accessor connections).
|
|
206
|
+
*/
|
|
207
|
+
label(label: string): LabeledQueries;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Wrap a `bun:sqlite` {@link Database} in place so every statement execution is
|
|
213
|
+
* timed and the slow ones are logged. The Drizzle path (`.prepare(sql)` then
|
|
214
|
+
* `.run()/.all()/.values()`), {@link ./raw-query} (`.query(sql).get()/.all()/
|
|
215
|
+
* .run()`), and the `Database.run(sql, params)` shortcut (used by migration
|
|
216
|
+
* code via `getSqliteFrom(db).run(...)`) all route through the entry points
|
|
217
|
+
* wrapped here, so a single call covers every path.
|
|
218
|
+
*
|
|
219
|
+
* Returns the same instance (mutated), so callers can wrap inline at
|
|
220
|
+
* construction. `.exec()` — batch DDL, PRAGMAs, and transaction `BEGIN`/`COMMIT`
|
|
221
|
+
* — is intentionally left unwrapped: it takes no bindings and isn't a
|
|
222
|
+
* statement-execution path. `options` exists only for tests.
|
|
223
|
+
*/
|
|
224
|
+
export function wrapSqliteForSlowQueryLogging(
|
|
225
|
+
sqlite: Database,
|
|
226
|
+
options: SlowQueryWatcherOptions = {},
|
|
227
|
+
): Database {
|
|
228
|
+
const thresholdMs = options.thresholdMs ?? SLOW_QUERY_THRESHOLD_MS;
|
|
229
|
+
const now = options.now ?? (() => performance.now());
|
|
230
|
+
const onSlowQuery = options.onSlowQuery ?? reportSlowQuery;
|
|
231
|
+
// Reuse the path this connection was opened with (`new Database(path)`) rather
|
|
232
|
+
// than a hand-passed key — its basename names the damaged file.
|
|
233
|
+
const database = basename(sqlite.filename);
|
|
234
|
+
|
|
235
|
+
// Slow path only (a statement threw). Surface it to the corruption watchdog;
|
|
236
|
+
// its failure must never escape into the query path.
|
|
237
|
+
const notifyError = (
|
|
238
|
+
err: unknown,
|
|
239
|
+
sql: string,
|
|
240
|
+
label: string | undefined,
|
|
241
|
+
): void => {
|
|
242
|
+
try {
|
|
243
|
+
observeSqliteStatementError(err, {
|
|
244
|
+
sql: sql.slice(0, SQL_PREVIEW_MAX),
|
|
245
|
+
database,
|
|
246
|
+
...(label === undefined ? {} : { label }),
|
|
247
|
+
});
|
|
248
|
+
} catch {
|
|
249
|
+
// The observer must never break the query path.
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// Re-entrancy guard. `bun:sqlite` implements `db.query(sql).run()` by
|
|
254
|
+
// delegating through the (also-wrapped) `db.prepare(sql)`, so the outer
|
|
255
|
+
// `.run()` would time the inner `.run()` a second time. Because `bun:sqlite`
|
|
256
|
+
// is fully synchronous, a per-connection flag safely collapses that nesting:
|
|
257
|
+
// only the outermost execution is timed (its duration already includes any
|
|
258
|
+
// inner re-prepare), inner ones pass straight through. Not shared across
|
|
259
|
+
// connections so tests stay isolated.
|
|
260
|
+
let timing = false;
|
|
261
|
+
|
|
262
|
+
const emit = (
|
|
263
|
+
sql: string,
|
|
264
|
+
label: string | undefined,
|
|
265
|
+
durationMs: number,
|
|
266
|
+
result: unknown,
|
|
267
|
+
): void => {
|
|
268
|
+
// Only ever called on the slow path, so building the payload — including the
|
|
269
|
+
// stack walk for unlabeled (Drizzle) queries — is fine.
|
|
270
|
+
const caller = label === undefined ? callerFromStack() : undefined;
|
|
271
|
+
onSlowQuery({
|
|
272
|
+
durationMs,
|
|
273
|
+
sql: sql.slice(0, SQL_PREVIEW_MAX),
|
|
274
|
+
...(Array.isArray(result) ? { rowCount: result.length } : {}),
|
|
275
|
+
...(label === undefined ? {} : { label }),
|
|
276
|
+
...(caller === undefined ? {} : { caller }),
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// Statement proxies are cached against their native statement so repeated
|
|
281
|
+
// executions of a `.query()`-cached prepared statement reuse one proxy and its
|
|
282
|
+
// timed closures — nothing allocates on the hot path. The cache is keyed by
|
|
283
|
+
// label as well as statement so a native statement reused under different
|
|
284
|
+
// labels gets one proxy per label (no label leaks across callers), and the
|
|
285
|
+
// labeled hot path (e.g. the raw-query helpers) stays allocation-free too.
|
|
286
|
+
const UNLABELED = "";
|
|
287
|
+
const proxiesByStmt = new WeakMap<Statement, Map<string, Statement>>();
|
|
288
|
+
|
|
289
|
+
const wrapStatement = (
|
|
290
|
+
stmt: Statement,
|
|
291
|
+
sql: string,
|
|
292
|
+
label: string | undefined,
|
|
293
|
+
): Statement => {
|
|
294
|
+
const cacheKey = label ?? UNLABELED;
|
|
295
|
+
let byLabel = proxiesByStmt.get(stmt);
|
|
296
|
+
if (byLabel) {
|
|
297
|
+
const cached = byLabel.get(cacheKey);
|
|
298
|
+
if (cached) return cached;
|
|
299
|
+
} else {
|
|
300
|
+
byLabel = new Map();
|
|
301
|
+
proxiesByStmt.set(stmt, byLabel);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const timed = new Map<string, (...args: unknown[]) => unknown>();
|
|
305
|
+
const proxy = new Proxy(stmt, {
|
|
306
|
+
get(target, prop) {
|
|
307
|
+
if (typeof prop === "string" && TIMED_METHODS.has(prop)) {
|
|
308
|
+
let fn = timed.get(prop);
|
|
309
|
+
if (!fn) {
|
|
310
|
+
const call = (
|
|
311
|
+
target as unknown as Record<string, (...a: unknown[]) => unknown>
|
|
312
|
+
)[prop].bind(target);
|
|
313
|
+
fn = (...args: unknown[]): unknown => {
|
|
314
|
+
if (timing) return call(...args); // inner re-entry: no timing
|
|
315
|
+
timing = true;
|
|
316
|
+
const start = now();
|
|
317
|
+
let result: unknown;
|
|
318
|
+
try {
|
|
319
|
+
result = call(...args);
|
|
320
|
+
return result;
|
|
321
|
+
} catch (err) {
|
|
322
|
+
// The failed op still blocked and still needs timing (below);
|
|
323
|
+
// surface it to the error observer before it propagates
|
|
324
|
+
// unchanged. Re-entrant inner calls short-circuit above
|
|
325
|
+
// (`if (timing)`), so a nested throw is observed once, here.
|
|
326
|
+
notifyError(err, sql, label);
|
|
327
|
+
throw err;
|
|
328
|
+
} finally {
|
|
329
|
+
timing = false;
|
|
330
|
+
// Fast path: one subtraction + one compare. Nothing is
|
|
331
|
+
// allocated or sliced unless we cross the threshold.
|
|
332
|
+
const durationMs = now() - start;
|
|
333
|
+
if (durationMs >= thresholdMs) {
|
|
334
|
+
emit(sql, label, durationMs, result);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
timed.set(prop, fn);
|
|
339
|
+
}
|
|
340
|
+
return fn;
|
|
341
|
+
}
|
|
342
|
+
// Everything else (columnNames, paramsCount, finalize, toString, …)
|
|
343
|
+
// passes straight through, bound to the real statement so native
|
|
344
|
+
// methods keep their `this`.
|
|
345
|
+
const value = Reflect.get(target, prop, target);
|
|
346
|
+
return typeof value === "function"
|
|
347
|
+
? (value as (...a: unknown[]) => unknown).bind(target)
|
|
348
|
+
: value;
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
byLabel.set(cacheKey, proxy);
|
|
353
|
+
return proxy;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
const originalQuery = sqlite.query.bind(sqlite);
|
|
357
|
+
const originalPrepare = sqlite.prepare.bind(sqlite);
|
|
358
|
+
const originalRun = sqlite.run.bind(sqlite);
|
|
359
|
+
|
|
360
|
+
// `.query()` / `.prepare()` compile the SQL, which reads the schema — on a
|
|
361
|
+
// file with a corrupt header ("file is not a database") that read throws
|
|
362
|
+
// *here*, before any execution method runs, so the error is surfaced to the
|
|
363
|
+
// observer at creation time too. (Malformed-*page* corruption instead
|
|
364
|
+
// surfaces at step time and is caught in the execution closures above.) A
|
|
365
|
+
// `query()` that delegates through the wrapped `prepare()` may notify twice;
|
|
366
|
+
// the observer's per-database debounce collapses that to one report.
|
|
367
|
+
const createStatement = (
|
|
368
|
+
create: (...a: unknown[]) => Statement,
|
|
369
|
+
sql: string,
|
|
370
|
+
label: string | undefined,
|
|
371
|
+
rest: unknown[],
|
|
372
|
+
): Statement => {
|
|
373
|
+
let stmt: Statement;
|
|
374
|
+
try {
|
|
375
|
+
stmt = create(sql, ...rest);
|
|
376
|
+
} catch (err) {
|
|
377
|
+
notifyError(err, sql, label);
|
|
378
|
+
throw err;
|
|
379
|
+
}
|
|
380
|
+
return wrapStatement(stmt, sql, label);
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const makeQuery =
|
|
384
|
+
(label: string | undefined) =>
|
|
385
|
+
(sql: string, ...rest: unknown[]): Statement =>
|
|
386
|
+
createStatement(
|
|
387
|
+
originalQuery as (...a: unknown[]) => Statement,
|
|
388
|
+
sql,
|
|
389
|
+
label,
|
|
390
|
+
rest,
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
const makePrepare =
|
|
394
|
+
(label: string | undefined) =>
|
|
395
|
+
(sql: string, ...rest: unknown[]): Statement =>
|
|
396
|
+
createStatement(
|
|
397
|
+
originalPrepare as (...a: unknown[]) => Statement,
|
|
398
|
+
sql,
|
|
399
|
+
label,
|
|
400
|
+
rest,
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
// `Database.run(sql, ...params)` is a native shortcut that does not route
|
|
404
|
+
// through `.prepare()`, so it is timed directly here. `sql` is an argument
|
|
405
|
+
// (not fixed per closure), so one closure per label reads it from the call.
|
|
406
|
+
const makeRun =
|
|
407
|
+
(label: string | undefined) =>
|
|
408
|
+
(sql: string, ...params: unknown[]): unknown => {
|
|
409
|
+
const call = originalRun as (...a: unknown[]) => unknown;
|
|
410
|
+
if (timing) return call(sql, ...params);
|
|
411
|
+
timing = true;
|
|
412
|
+
const start = now();
|
|
413
|
+
let result: unknown;
|
|
414
|
+
try {
|
|
415
|
+
result = call(sql, ...params);
|
|
416
|
+
return result;
|
|
417
|
+
} catch (err) {
|
|
418
|
+
notifyError(err, sql, label);
|
|
419
|
+
throw err;
|
|
420
|
+
} finally {
|
|
421
|
+
timing = false;
|
|
422
|
+
const durationMs = now() - start;
|
|
423
|
+
if (durationMs >= thresholdMs) emit(sql, label, durationMs, result);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
sqlite.query = makeQuery(undefined) as typeof sqlite.query;
|
|
428
|
+
sqlite.prepare = makePrepare(undefined) as typeof sqlite.prepare;
|
|
429
|
+
sqlite.run = makeRun(undefined) as typeof sqlite.run;
|
|
430
|
+
sqlite.label = (label: string): LabeledQueries => ({
|
|
431
|
+
query: makeQuery(label),
|
|
432
|
+
prepare: makePrepare(label),
|
|
433
|
+
run: makeRun(label) as LabeledQueries["run"],
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
return sqlite;
|
|
437
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribution for event-loop stalls caused by synchronous SQLite work.
|
|
3
|
+
*
|
|
4
|
+
* `bun:sqlite` runs on the daemon's single event-loop thread, so any slow
|
|
5
|
+
* statement — a large conversation-history load, a memory scan, a WAL
|
|
6
|
+
* checkpoint folding a multi-GB WAL — freezes every other handler (SSE,
|
|
7
|
+
* HTTP, health) for its full duration. The event-loop watchdog
|
|
8
|
+
* (`daemon/event-loop-watchdog.ts`) detects *that* a freeze happened but,
|
|
9
|
+
* being single-threaded itself, cannot capture *what* was running: by the
|
|
10
|
+
* time its tick fires the blocking call has returned and its stack is gone.
|
|
11
|
+
*
|
|
12
|
+
* This module fills that gap two ways:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Threshold reports** — wrap a known-heavy synchronous section with
|
|
15
|
+
* {@link timeSyncSection} (or call {@link reportSlowSync} with a measured
|
|
16
|
+
* duration); when it blocks past {@link SLOW_SYNC_THRESHOLD_MS} it logs a
|
|
17
|
+
* structured warning naming the call site and records a `watchdog`
|
|
18
|
+
* telemetry event. The threshold is deliberately below the watchdog's own
|
|
19
|
+
* 5s floor so sub-watchdog contributors are still named. Override with
|
|
20
|
+
* `VELLUM_SLOW_SYNC_THRESHOLD_MS`.
|
|
21
|
+
*
|
|
22
|
+
* 2. **Section trail** — a small in-memory ring of the most recently entered
|
|
23
|
+
* instrumented sections ({@link markSection} / {@link traceAsyncSection};
|
|
24
|
+
* {@link timeSyncSection} marks automatically). The event-loop watchdog
|
|
25
|
+
* attaches {@link getSectionTrail} to every freeze report: because the
|
|
26
|
+
* loop is single-threaded, the newest mark still un-ended at block start
|
|
27
|
+
* (entries older than `blockedMs`) names — or tightly brackets — the code
|
|
28
|
+
* that froze, even when the block sits in a section nobody thought to
|
|
29
|
+
* time. Marks record only static labels, never content.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { getLogger } from "../util/logger.js";
|
|
33
|
+
|
|
34
|
+
const log = getLogger("slow-sync");
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Synchronous sections that block the event loop at least this long are
|
|
38
|
+
* reported. Env-overridable for tuning attribution verbosity on a busy
|
|
39
|
+
* host without a rebuild; falls back to 1000ms for any non-positive or
|
|
40
|
+
* unparseable value.
|
|
41
|
+
*/
|
|
42
|
+
export const SLOW_SYNC_THRESHOLD_MS = ((): number => {
|
|
43
|
+
const raw = Number(process.env.VELLUM_SLOW_SYNC_THRESHOLD_MS);
|
|
44
|
+
return Number.isFinite(raw) && raw > 0 ? raw : 1000;
|
|
45
|
+
})();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* `check_name` for slow-sync telemetry events. Stable so downstream
|
|
49
|
+
* grouping stays consistent; keep it in sync with any admin query.
|
|
50
|
+
*/
|
|
51
|
+
export const SLOW_SYNC_CHECK_NAME = "slow_sync_operation";
|
|
52
|
+
|
|
53
|
+
/** One recorded section entry: a static label plus monotonic start/end stamps. */
|
|
54
|
+
export interface SectionMark {
|
|
55
|
+
label: string;
|
|
56
|
+
startedAt: number;
|
|
57
|
+
endedAt?: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* How many section marks the trail retains. Sized so the sections between a
|
|
62
|
+
* container mark (e.g. an agent-event dispatch) and a freeze — typically a
|
|
63
|
+
* handful of nested query marks — don't evict the container before the
|
|
64
|
+
* watchdog reads the trail.
|
|
65
|
+
*/
|
|
66
|
+
const SECTION_TRAIL_CAPACITY = 16;
|
|
67
|
+
|
|
68
|
+
const sectionTrail: SectionMark[] = [];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Record that an instrumented section is starting. Returns the mark so the
|
|
72
|
+
* caller can stamp its completion with {@link endSection}. Cheap enough for
|
|
73
|
+
* hot paths: one small allocation and a bounded-array push.
|
|
74
|
+
*/
|
|
75
|
+
export function markSection(label: string): SectionMark {
|
|
76
|
+
const mark: SectionMark = { label, startedAt: performance.now() };
|
|
77
|
+
sectionTrail.push(mark);
|
|
78
|
+
if (sectionTrail.length > SECTION_TRAIL_CAPACITY) {
|
|
79
|
+
sectionTrail.shift();
|
|
80
|
+
}
|
|
81
|
+
return mark;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Stamp a mark's completion; returns the section's elapsed milliseconds. */
|
|
85
|
+
export function endSection(mark: SectionMark): number {
|
|
86
|
+
mark.endedAt = performance.now();
|
|
87
|
+
return mark.endedAt - mark.startedAt;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Trail a section that spans an `await` (a hook chain, a provider call). The
|
|
92
|
+
* mark stays open for the span's full wall time — sections entered by work
|
|
93
|
+
* interleaving on the loop during the await appear as newer trail entries, so
|
|
94
|
+
* a freeze inside the span is still bracketed correctly. Wall time is NOT
|
|
95
|
+
* reported as a slow sync: an awaited span legitimately spends most of it
|
|
96
|
+
* off-loop.
|
|
97
|
+
*/
|
|
98
|
+
export async function traceAsyncSection<T>(
|
|
99
|
+
label: string,
|
|
100
|
+
fn: () => Promise<T>,
|
|
101
|
+
): Promise<T> {
|
|
102
|
+
const mark = markSection(label);
|
|
103
|
+
try {
|
|
104
|
+
return await fn();
|
|
105
|
+
} finally {
|
|
106
|
+
endSection(mark);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** A trail entry made relative to "now" for freeze reports. */
|
|
111
|
+
export interface SectionTrailEntry {
|
|
112
|
+
label: string;
|
|
113
|
+
startedAgoMs: number;
|
|
114
|
+
/** Absent while the section is still running (or never ended). */
|
|
115
|
+
endedAgoMs?: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Newest-first snapshot of recent section marks, ages relative to `now`.
|
|
120
|
+
* Reading it against a freeze report: the block began ~`blockedMs` ago, so
|
|
121
|
+
* the newest entry with `startedAgoMs >= blockedMs` that has no `endedAgoMs`
|
|
122
|
+
* (or ended after the block began) is the section that was running when the
|
|
123
|
+
* loop froze.
|
|
124
|
+
*/
|
|
125
|
+
export function getSectionTrail(
|
|
126
|
+
now: number = performance.now(),
|
|
127
|
+
): SectionTrailEntry[] {
|
|
128
|
+
return [...sectionTrail].reverse().map((mark) => ({
|
|
129
|
+
label: mark.label,
|
|
130
|
+
startedAgoMs: Math.round(now - mark.startedAt),
|
|
131
|
+
...(mark.endedAt !== undefined
|
|
132
|
+
? { endedAgoMs: Math.round(now - mark.endedAt) }
|
|
133
|
+
: {}),
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Test isolation only — the trail is process-global module state. */
|
|
138
|
+
export function resetSectionTrailForTests(): void {
|
|
139
|
+
sectionTrail.length = 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Report a synchronous section that blocked the event loop for `elapsedMs`.
|
|
144
|
+
* No-op below {@link SLOW_SYNC_THRESHOLD_MS}. `label` names the call site
|
|
145
|
+
* (e.g. `conversation:load-from-db`); `detail` carries attribution context
|
|
146
|
+
* (conversation id, row count, SQL preview) — never conversation content.
|
|
147
|
+
*/
|
|
148
|
+
export function reportSlowSync(
|
|
149
|
+
label: string,
|
|
150
|
+
elapsedMs: number,
|
|
151
|
+
detail?: Record<string, unknown>,
|
|
152
|
+
): void {
|
|
153
|
+
if (elapsedMs < SLOW_SYNC_THRESHOLD_MS) return;
|
|
154
|
+
log.warn(
|
|
155
|
+
{ label, elapsedMs, ...detail },
|
|
156
|
+
"Slow synchronous DB operation blocked the event loop",
|
|
157
|
+
);
|
|
158
|
+
// Record telemetry via a lazy dynamic import. A static import would pull the
|
|
159
|
+
// telemetry → consent-cache → config/loader chain into the module graph of
|
|
160
|
+
// every raw-query / conversation-load caller, where a test's `mock.module`
|
|
161
|
+
// of the loader leaks across the shared test process and breaks unrelated
|
|
162
|
+
// files at eval time. Loading it only on the rare slow path keeps that chain
|
|
163
|
+
// off the hot path's static graph; best-effort, so a failure is swallowed.
|
|
164
|
+
void import("../telemetry/watchdog-events-store.js")
|
|
165
|
+
.then(({ recordWatchdogEvent }) => {
|
|
166
|
+
recordWatchdogEvent({
|
|
167
|
+
checkName: SLOW_SYNC_CHECK_NAME,
|
|
168
|
+
value: elapsedMs,
|
|
169
|
+
detail: { label, ...detail },
|
|
170
|
+
});
|
|
171
|
+
})
|
|
172
|
+
.catch(() => {
|
|
173
|
+
// Telemetry is best-effort — never let it escape the timed section.
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Time a synchronous section, returning its value, and {@link reportSlowSync}
|
|
179
|
+
* it when it blocks past the threshold. Every section also lands in the
|
|
180
|
+
* section trail, so watchdog freeze reports can place it on the timeline.
|
|
181
|
+
* `detail` is evaluated only on success, from the section's result, so it can
|
|
182
|
+
* report a computed count. A thrown error is still reported (the failed op
|
|
183
|
+
* still blocked) and then rethrown unchanged.
|
|
184
|
+
*/
|
|
185
|
+
export function timeSyncSection<T>(
|
|
186
|
+
label: string,
|
|
187
|
+
fn: () => T,
|
|
188
|
+
detail?: (result: T) => Record<string, unknown>,
|
|
189
|
+
): T {
|
|
190
|
+
const mark = markSection(label);
|
|
191
|
+
try {
|
|
192
|
+
const result = fn();
|
|
193
|
+
const elapsedMs = endSection(mark);
|
|
194
|
+
// Build `detail` only when actually reporting — the section runs on hot
|
|
195
|
+
// query paths, so the thunk must not allocate on the sub-threshold path.
|
|
196
|
+
if (elapsedMs >= SLOW_SYNC_THRESHOLD_MS) {
|
|
197
|
+
reportSlowSync(label, elapsedMs, detail?.(result));
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
} catch (err) {
|
|
201
|
+
reportSlowSync(label, endSection(mark));
|
|
202
|
+
throw err;
|
|
203
|
+
}
|
|
204
|
+
}
|
package/src/persistence/steps.ts
CHANGED
|
@@ -418,6 +418,14 @@ import { migrateAcpSessionHistoryUsageColumns } from "./migrations/307-acp-sessi
|
|
|
418
418
|
import { migrateAcpSessionHistoryTokenColumns } from "./migrations/308-acp-session-history-token-columns.js";
|
|
419
419
|
import { migrateDropRedundantIndexes } from "./migrations/309-drop-redundant-indexes.js";
|
|
420
420
|
import { migrateLlmRequestLogLatencyBreakdown } from "./migrations/310-llm-request-log-latency-breakdown.js";
|
|
421
|
+
import { migrateCreateSubagentsTable } from "./migrations/311-create-subagents-table.js";
|
|
422
|
+
import { migrateDropInboxConversationStateTable } from "./migrations/312-drop-inbox-conversation-state-table.js";
|
|
423
|
+
import { migrateDropMessagesFts } from "./migrations/313-drop-messages-fts.js";
|
|
424
|
+
import { migrateAddConversationEnabledPlugins } from "./migrations/314-add-conversation-enabled-plugins.js";
|
|
425
|
+
import { migrateCreateA2aInvitesTable } from "./migrations/315-create-a2a-invites.js";
|
|
426
|
+
import { migrateDropContactChannelInviteId } from "./migrations/316-drop-contact-channels-invite-id.js";
|
|
427
|
+
import { migrateCanonicalGuardianRequesterSignals } from "./migrations/317-canonical-guardian-requester-signals.js";
|
|
428
|
+
import { migrateDropContactChannelTelemetry } from "./migrations/318-drop-contact-channel-telemetry.js";
|
|
421
429
|
import type { MigrationStep } from "./migrations/run-migrations.js";
|
|
422
430
|
|
|
423
431
|
export const migrationSteps: MigrationStep[] = [
|
|
@@ -1307,4 +1315,12 @@ export const migrationSteps: MigrationStep[] = [
|
|
|
1307
1315
|
migrateAcpSessionHistoryTokenColumns,
|
|
1308
1316
|
migrateDropRedundantIndexes,
|
|
1309
1317
|
migrateLlmRequestLogLatencyBreakdown,
|
|
1318
|
+
migrateCreateSubagentsTable,
|
|
1319
|
+
migrateDropInboxConversationStateTable,
|
|
1320
|
+
migrateDropMessagesFts,
|
|
1321
|
+
migrateAddConversationEnabledPlugins,
|
|
1322
|
+
migrateCreateA2aInvitesTable,
|
|
1323
|
+
migrateDropContactChannelInviteId,
|
|
1324
|
+
migrateCanonicalGuardianRequesterSignals,
|
|
1325
|
+
migrateDropContactChannelTelemetry,
|
|
1310
1326
|
];
|