@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,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedule worker control endpoints (start / stop / status).
|
|
3
|
+
*
|
|
4
|
+
* These run inside the daemon so the worker process the daemon spawns is a
|
|
5
|
+
* direct child of the daemon — which is what makes it show up in the daemon's
|
|
6
|
+
* process tree (`assistant ps`) and lets the daemon tear it down on shutdown.
|
|
7
|
+
* The `assistant schedules worker` CLI is a thin IPC client over these routes;
|
|
8
|
+
* if it spawned the worker itself, the worker would be parented to the
|
|
9
|
+
* short-lived CLI process (reparented to init) instead of the daemon.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
getConfigReadOnly,
|
|
16
|
+
loadRawConfig,
|
|
17
|
+
saveRawConfig,
|
|
18
|
+
setNestedValue,
|
|
19
|
+
} from "../../config/loader.js";
|
|
20
|
+
import {
|
|
21
|
+
probeScheduleWorker,
|
|
22
|
+
ScheduleWorkerSpawnError,
|
|
23
|
+
spawnScheduleWorkerProcess,
|
|
24
|
+
stopScheduleWorkerProcess,
|
|
25
|
+
} from "../../schedule/worker-control.js";
|
|
26
|
+
import { getLogger } from "../../util/logger.js";
|
|
27
|
+
import { getScheduleWorkerPidPath } from "../../util/platform.js";
|
|
28
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
29
|
+
import { InternalError } from "./errors.js";
|
|
30
|
+
import type { RouteDefinition } from "./types.js";
|
|
31
|
+
|
|
32
|
+
const log = getLogger("schedule-worker-routes");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Persist `schedules.worker.enabled` to the on-disk config via the shared
|
|
36
|
+
* raw-config helpers, so only this leaf changes (schema defaults are not baked
|
|
37
|
+
* into the file). The daemon's scheduler re-reads the flag on its next tick,
|
|
38
|
+
* so the change takes effect without a restart.
|
|
39
|
+
*/
|
|
40
|
+
function setScheduleWorkerEnabled(enabled: boolean): void {
|
|
41
|
+
const raw = loadRawConfig();
|
|
42
|
+
setNestedValue(raw, "schedules.worker.enabled", enabled);
|
|
43
|
+
saveRawConfig(raw);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const workerStatusSchema = z.object({
|
|
47
|
+
status: z.enum(["running", "not_running"]),
|
|
48
|
+
pid: z.number().optional(),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const startResponseSchema = z.object({
|
|
52
|
+
pid: z.number(),
|
|
53
|
+
alreadyRunning: z.boolean(),
|
|
54
|
+
workerEnabled: z.literal(true),
|
|
55
|
+
pidPath: z.string(),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const stopResponseSchema = z.object({
|
|
59
|
+
workerWasRunning: z.boolean(),
|
|
60
|
+
pid: z.number().optional(),
|
|
61
|
+
workerEnabled: z.literal(false),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const statusResponseSchema = z.object({
|
|
65
|
+
status: z.enum(["running", "not_running"]),
|
|
66
|
+
pid: z.number().optional(),
|
|
67
|
+
workerEnabled: z.boolean(),
|
|
68
|
+
inProcessScheduler: workerStatusSchema,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Start (or reuse) the schedule worker process as a child of the daemon, then
|
|
73
|
+
* enable `schedules.worker.enabled` so the daemon's scheduler leaves schedule
|
|
74
|
+
* execution to it. The flag is only enabled once the worker is confirmed up —
|
|
75
|
+
* on spawn failure it is left untouched so the in-process scheduler keeps
|
|
76
|
+
* running schedules rather than standing down for a worker that never came
|
|
77
|
+
* up.
|
|
78
|
+
*/
|
|
79
|
+
async function startScheduleWorker() {
|
|
80
|
+
let result: { pid: number; alreadyRunning: boolean };
|
|
81
|
+
try {
|
|
82
|
+
// `detached: false` parents the worker to the daemon. `terminateOnTimeout`
|
|
83
|
+
// matches the leave-the-flag-off-on-failure contract below: a worker that
|
|
84
|
+
// came up late would otherwise run schedules alongside the in-process
|
|
85
|
+
// scheduler.
|
|
86
|
+
result = await spawnScheduleWorkerProcess({
|
|
87
|
+
detached: false,
|
|
88
|
+
terminateOnTimeout: true,
|
|
89
|
+
});
|
|
90
|
+
} catch (err) {
|
|
91
|
+
const message =
|
|
92
|
+
err instanceof ScheduleWorkerSpawnError || err instanceof Error
|
|
93
|
+
? err.message
|
|
94
|
+
: String(err);
|
|
95
|
+
log.warn({ err }, "Failed to start schedule worker process");
|
|
96
|
+
throw new InternalError(message);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setScheduleWorkerEnabled(true);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
pid: result.pid,
|
|
103
|
+
alreadyRunning: result.alreadyRunning,
|
|
104
|
+
workerEnabled: true as const,
|
|
105
|
+
pidPath: getScheduleWorkerPidPath(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Disable `schedules.worker.enabled` (handing schedule execution back to the
|
|
111
|
+
* in-process scheduler) and SIGTERM the worker process if it is running. A
|
|
112
|
+
* worker that is not running is not an error — flipping the flag alone
|
|
113
|
+
* restores in-process execution.
|
|
114
|
+
*/
|
|
115
|
+
function stopScheduleWorker() {
|
|
116
|
+
setScheduleWorkerEnabled(false);
|
|
117
|
+
|
|
118
|
+
let before: ReturnType<typeof stopScheduleWorkerProcess>;
|
|
119
|
+
try {
|
|
120
|
+
before = stopScheduleWorkerProcess();
|
|
121
|
+
} catch (err) {
|
|
122
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
+
log.warn({ err }, "Failed to signal schedule worker process");
|
|
124
|
+
throw new InternalError(message);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
workerWasRunning: before.status === "running",
|
|
129
|
+
...(before.pid != null ? { pid: before.pid } : {}),
|
|
130
|
+
workerEnabled: false as const,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Report the worker process state, the `schedules.worker.enabled` config
|
|
136
|
+
* value, and whether the daemon's own scheduler is currently executing
|
|
137
|
+
* schedules.
|
|
138
|
+
*
|
|
139
|
+
* The in-process scheduler executes schedules exactly when the flag is off
|
|
140
|
+
* (it stands down from claiming while the flag is on). This handler runs
|
|
141
|
+
* inside the daemon — the very process that is (or isn't) the in-process
|
|
142
|
+
* scheduler — so its state is derived directly from config, with the
|
|
143
|
+
* daemon's own PID, rather than read back from a marker file.
|
|
144
|
+
*/
|
|
145
|
+
function scheduleWorkerStatus() {
|
|
146
|
+
const worker = probeScheduleWorker();
|
|
147
|
+
const workerEnabled = getConfigReadOnly().schedules.worker.enabled;
|
|
148
|
+
|
|
149
|
+
const inProcessScheduler: {
|
|
150
|
+
status: "running" | "not_running";
|
|
151
|
+
pid?: number;
|
|
152
|
+
} = workerEnabled
|
|
153
|
+
? { status: "not_running" }
|
|
154
|
+
: { status: "running", pid: process.pid };
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
status: worker.status,
|
|
158
|
+
...(worker.pid != null ? { pid: worker.pid } : {}),
|
|
159
|
+
workerEnabled,
|
|
160
|
+
inProcessScheduler,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const ROUTES: RouteDefinition[] = [
|
|
165
|
+
{
|
|
166
|
+
operationId: "schedules_worker_start",
|
|
167
|
+
endpoint: "schedules/worker/start",
|
|
168
|
+
method: "POST",
|
|
169
|
+
policy: {
|
|
170
|
+
requiredScopes: ["settings.write"],
|
|
171
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
172
|
+
},
|
|
173
|
+
handler: startScheduleWorker,
|
|
174
|
+
summary: "Start the schedule worker",
|
|
175
|
+
description:
|
|
176
|
+
"Spawns (or reuses) the schedule worker process as a child of the daemon and enables schedules.worker.enabled, so scheduled jobs run out of process.",
|
|
177
|
+
tags: ["system"],
|
|
178
|
+
responseBody: startResponseSchema,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
operationId: "schedules_worker_stop",
|
|
182
|
+
endpoint: "schedules/worker/stop",
|
|
183
|
+
method: "POST",
|
|
184
|
+
policy: {
|
|
185
|
+
requiredScopes: ["settings.write"],
|
|
186
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
187
|
+
},
|
|
188
|
+
handler: stopScheduleWorker,
|
|
189
|
+
summary: "Stop the schedule worker",
|
|
190
|
+
description:
|
|
191
|
+
"Disables schedules.worker.enabled (handing schedule execution back to the in-process scheduler) and SIGTERMs the schedule worker process if it is running.",
|
|
192
|
+
tags: ["system"],
|
|
193
|
+
responseBody: stopResponseSchema,
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
operationId: "schedules_worker_status",
|
|
197
|
+
endpoint: "schedules/worker/status",
|
|
198
|
+
method: "GET",
|
|
199
|
+
policy: {
|
|
200
|
+
requiredScopes: ["settings.read"],
|
|
201
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
202
|
+
},
|
|
203
|
+
handler: scheduleWorkerStatus,
|
|
204
|
+
summary: "Schedule worker status",
|
|
205
|
+
description:
|
|
206
|
+
"Reports the schedule worker process state, schedules.worker.enabled, and whether the daemon's in-process scheduler is currently executing schedules.",
|
|
207
|
+
tags: ["system"],
|
|
208
|
+
responseBody: statusResponseSchema,
|
|
209
|
+
},
|
|
210
|
+
];
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
import { getCesClient } from "../../credential-execution/ces-runtime.js";
|
|
25
25
|
import type { CesClient } from "../../credential-execution/client.js";
|
|
26
26
|
import { evictConversationsForReload } from "../../daemon/conversation-store.js";
|
|
27
|
-
import { maybeReseedCapabilitiesAfterManagedCredential } from "../../daemon/memory-v2-startup.js";
|
|
28
27
|
import { setSentryOrganizationId, setSentryUserId } from "../../instrument.js";
|
|
29
28
|
import { syncManualTokenConnection } from "../../oauth/manual-token-connection.js";
|
|
30
29
|
import { clearEmbeddingBackendCache } from "../../persistence/embeddings/embedding-backend.js";
|
|
30
|
+
import { maybeReseedCapabilitiesAfterManagedCredential } from "../../plugins/defaults/memory/v2/memory-v2-startup.js";
|
|
31
31
|
import { validateAnthropicApiKey } from "../../providers/anthropic/client.js";
|
|
32
32
|
import { validateAtlasCloudApiKey } from "../../providers/atlascloud/client.js";
|
|
33
33
|
import { validateGeminiApiKey } from "../../providers/gemini/client.js";
|
|
@@ -53,6 +53,7 @@ export async function resolveSurfaceConversation(
|
|
|
53
53
|
// unrelated rows.
|
|
54
54
|
const escaped = surfaceId.replace(/[\\%_]/g, "\\$&");
|
|
55
55
|
const row = rawGet<{ conversation_id: string }>(
|
|
56
|
+
"surfaceResolver:resolveConversation",
|
|
56
57
|
`SELECT conversation_id FROM messages
|
|
57
58
|
WHERE content LIKE ? ESCAPE '\\'
|
|
58
59
|
ORDER BY created_at DESC
|
|
@@ -29,7 +29,18 @@ const mockGetMessages = mock(
|
|
|
29
29
|
const mockCreateConversation = mock((_opts?: Record<string, unknown>) => ({
|
|
30
30
|
id: "analysis-new",
|
|
31
31
|
}));
|
|
32
|
-
|
|
32
|
+
// Echo back the caller-supplied row id (the request id, under the
|
|
33
|
+
// requestId-as-row-id invariant) so tests can assert the persisted message
|
|
34
|
+
// row id matches the turn's request id. Falls back to "msg-1" when no id is
|
|
35
|
+
// passed.
|
|
36
|
+
const mockAddMessage = mock(
|
|
37
|
+
async (
|
|
38
|
+
_conversationId: string,
|
|
39
|
+
_role: string,
|
|
40
|
+
_content: string,
|
|
41
|
+
opts?: { id?: string },
|
|
42
|
+
) => ({ id: opts?.id ?? "msg-1" }),
|
|
43
|
+
);
|
|
33
44
|
const mockFindAnalysisConversationFor = mock(
|
|
34
45
|
(_parent: string) => null as { id: string } | null,
|
|
35
46
|
);
|
|
@@ -106,7 +117,14 @@ beforeEach(() => {
|
|
|
106
117
|
mockCreateConversation.mockReset();
|
|
107
118
|
mockCreateConversation.mockImplementation(() => ({ id: "analysis-new" }));
|
|
108
119
|
mockAddMessage.mockReset();
|
|
109
|
-
mockAddMessage.mockImplementation(
|
|
120
|
+
mockAddMessage.mockImplementation(
|
|
121
|
+
async (
|
|
122
|
+
_conversationId: string,
|
|
123
|
+
_role: string,
|
|
124
|
+
_content: string,
|
|
125
|
+
opts?: { id?: string },
|
|
126
|
+
) => ({ id: opts?.id ?? "msg-1" }),
|
|
127
|
+
);
|
|
110
128
|
mockFindAnalysisConversationFor.mockReset();
|
|
111
129
|
mockFindAnalysisConversationFor.mockImplementation(() => null);
|
|
112
130
|
mockGetConversationSource.mockReset();
|
|
@@ -168,12 +186,13 @@ describe("analyzeConversation", () => {
|
|
|
168
186
|
if ("error" in result) throw new Error("expected success");
|
|
169
187
|
expect(result.analysisConversationId).toBe("analysis-new");
|
|
170
188
|
|
|
171
|
-
// Persists the prompt as a user message with unknown trust
|
|
189
|
+
// Persists the prompt as a user message with unknown trust, under a
|
|
190
|
+
// caller-minted row id (the turn's request id).
|
|
172
191
|
expect(mockAddMessage).toHaveBeenCalledWith(
|
|
173
192
|
"analysis-new",
|
|
174
193
|
"user",
|
|
175
194
|
expect.any(String),
|
|
176
|
-
{ metadata: { provenanceTrustClass: "unknown" } },
|
|
195
|
+
{ id: expect.any(String), metadata: { provenanceTrustClass: "unknown" } },
|
|
177
196
|
);
|
|
178
197
|
|
|
179
198
|
// Sets trust context to unknown.
|
|
@@ -193,11 +212,23 @@ describe("analyzeConversation", () => {
|
|
|
193
212
|
expect(allowedTools).toBeInstanceOf(Set);
|
|
194
213
|
expect(allowedTools?.size).toBe(0);
|
|
195
214
|
|
|
215
|
+
// requestId === userMessageId invariant: the id the prompt row was
|
|
216
|
+
// persisted under, the turn's currentRequestId, and the userMessageId
|
|
217
|
+
// handed to the agent loop are all the same value.
|
|
218
|
+
const persistedId = (
|
|
219
|
+
mockAddMessage.mock.calls as unknown as Array<
|
|
220
|
+
[string, string, string, { id?: string } | undefined]
|
|
221
|
+
>
|
|
222
|
+
)[0]?.[3]?.id;
|
|
223
|
+
expect(typeof persistedId).toBe("string");
|
|
224
|
+
expect(currentConversation.currentRequestId).toBe(persistedId ?? null);
|
|
225
|
+
|
|
196
226
|
// Fires the agent loop with the analyzeConversation call-site so the
|
|
197
|
-
// per-call provider config flows through `resolveCallSiteConfig
|
|
227
|
+
// per-call provider config flows through `resolveCallSiteConfig`, keying
|
|
228
|
+
// the loop off the same id as userMessageId.
|
|
198
229
|
expect(currentConversation.runAgentLoop).toHaveBeenCalledWith(
|
|
199
230
|
expect.any(String),
|
|
200
|
-
|
|
231
|
+
persistedId,
|
|
201
232
|
expect.objectContaining({
|
|
202
233
|
isInteractive: false,
|
|
203
234
|
isUserMessage: true,
|
|
@@ -287,12 +318,16 @@ describe("analyzeConversation", () => {
|
|
|
287
318
|
// No new conversation row is created on reuse.
|
|
288
319
|
expect(mockCreateConversation).not.toHaveBeenCalled();
|
|
289
320
|
|
|
290
|
-
// The new user message is appended to the existing analysis conversation
|
|
321
|
+
// The new user message is appended to the existing analysis conversation,
|
|
322
|
+
// persisted under the turn's request id.
|
|
291
323
|
expect(mockAddMessage).toHaveBeenCalledWith(
|
|
292
324
|
"analysis-existing",
|
|
293
325
|
"user",
|
|
294
326
|
expect.any(String),
|
|
295
|
-
{
|
|
327
|
+
{
|
|
328
|
+
id: expect.any(String),
|
|
329
|
+
metadata: { provenanceTrustClass: "guardian" },
|
|
330
|
+
},
|
|
296
331
|
);
|
|
297
332
|
});
|
|
298
333
|
|
|
@@ -406,9 +441,19 @@ describe("analyzeConversation", () => {
|
|
|
406
441
|
test("auto: routes the agent loop through callSite: 'analyzeConversation'", async () => {
|
|
407
442
|
await analyzeConversation("conv-1", { trigger: "auto" });
|
|
408
443
|
|
|
444
|
+
// Same requestId === userMessageId invariant on the auto path: the row
|
|
445
|
+
// id the prompt was persisted under, currentRequestId, and the loop's
|
|
446
|
+
// userMessageId are the same value.
|
|
447
|
+
const persistedId = (
|
|
448
|
+
mockAddMessage.mock.calls as unknown as Array<
|
|
449
|
+
[string, string, string, { id?: string } | undefined]
|
|
450
|
+
>
|
|
451
|
+
)[0]?.[3]?.id;
|
|
452
|
+
expect(typeof persistedId).toBe("string");
|
|
453
|
+
expect(currentConversation.currentRequestId).toBe(persistedId ?? null);
|
|
409
454
|
expect(currentConversation.runAgentLoop).toHaveBeenCalledWith(
|
|
410
455
|
expect.any(String),
|
|
411
|
-
|
|
456
|
+
persistedId,
|
|
412
457
|
expect.objectContaining({ callSite: "analyzeConversation" }),
|
|
413
458
|
);
|
|
414
459
|
});
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
afterAll,
|
|
3
|
+
beforeAll,
|
|
4
|
+
beforeEach,
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
mock,
|
|
8
|
+
test,
|
|
9
|
+
} from "bun:test";
|
|
2
10
|
|
|
3
11
|
mock.module("../../../util/logger.js", () => ({
|
|
4
12
|
getLogger: () =>
|
|
@@ -42,11 +50,6 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
|
42
50
|
flagEnabled,
|
|
43
51
|
}));
|
|
44
52
|
|
|
45
|
-
mock.module("../auto-analysis-guard.js", () => ({
|
|
46
|
-
AUTO_ANALYSIS_SOURCE: "auto-analysis",
|
|
47
|
-
isAutoAnalysisConversation: (_conversationId: string) => isAuto,
|
|
48
|
-
}));
|
|
49
|
-
|
|
50
53
|
mock.module(
|
|
51
54
|
"../../../plugins/defaults/memory/memory-retrospective-enqueue.js",
|
|
52
55
|
() => ({
|
|
@@ -79,6 +82,27 @@ mock.module("../../../persistence/jobs-store.js", () => ({
|
|
|
79
82
|
},
|
|
80
83
|
}));
|
|
81
84
|
|
|
85
|
+
// Scope the sibling `auto-analysis-guard` stub to this suite so it does not
|
|
86
|
+
// leak into auto-analysis-guard.test.ts, which exercises the real
|
|
87
|
+
// `isAutoAnalysisConversation` in the same Bun process. Bun's `mock.module` is
|
|
88
|
+
// process-global and not undone by `mock.restore()`; the capture spreads into a
|
|
89
|
+
// plain object to freeze the real export by value (a namespace reference is a
|
|
90
|
+
// live view that `mock.module` mutates in place).
|
|
91
|
+
const actualAutoAnalysisGuard = {
|
|
92
|
+
...(await import("../auto-analysis-guard.js")),
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
beforeAll(() => {
|
|
96
|
+
mock.module("../auto-analysis-guard.js", () => ({
|
|
97
|
+
AUTO_ANALYSIS_SOURCE: "auto-analysis",
|
|
98
|
+
isAutoAnalysisConversation: (_conversationId: string) => isAuto,
|
|
99
|
+
}));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
afterAll(() => {
|
|
103
|
+
mock.module("../auto-analysis-guard.js", () => actualAutoAnalysisGuard);
|
|
104
|
+
});
|
|
105
|
+
|
|
82
106
|
import {
|
|
83
107
|
enqueueAutoAnalysisIfEnabled,
|
|
84
108
|
enqueueAutoAnalysisOnCompaction,
|
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
* wiring.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
afterAll,
|
|
11
|
+
beforeAll,
|
|
12
|
+
beforeEach,
|
|
13
|
+
describe,
|
|
14
|
+
expect,
|
|
15
|
+
mock,
|
|
16
|
+
test,
|
|
17
|
+
} from "bun:test";
|
|
10
18
|
|
|
11
19
|
mock.module("../../../util/logger.js", () => ({
|
|
12
20
|
getLogger: () =>
|
|
@@ -34,10 +42,6 @@ const mockAnalyzeConversation = mock(
|
|
|
34
42
|
},
|
|
35
43
|
);
|
|
36
44
|
|
|
37
|
-
mock.module("../analyze-conversation.js", () => ({
|
|
38
|
-
analyzeConversation: mockAnalyzeConversation,
|
|
39
|
-
}));
|
|
40
|
-
|
|
41
45
|
// Mock auto-analysis-enqueue — track calls so we can verify requeue behavior.
|
|
42
46
|
type EnqueueArgs = {
|
|
43
47
|
conversationId: string;
|
|
@@ -48,9 +52,40 @@ const mockEnqueueAutoAnalysisIfEnabled = mock((args: EnqueueArgs) => {
|
|
|
48
52
|
enqueueCalls.push(args);
|
|
49
53
|
});
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
// Scope the sibling-module stubs to this suite's lifecycle. Bun's `mock.module`
|
|
56
|
+
// is process-global and is NOT undone by `mock.restore()`, so registering these
|
|
57
|
+
// at the top level leaks the stubs into sibling suites that import the real
|
|
58
|
+
// modules in the same Bun process (analyze-conversation.test.ts,
|
|
59
|
+
// auto-analysis-enqueue.test.ts). Register the stubs in `beforeAll` and
|
|
60
|
+
// re-register the real modules in `afterAll`.
|
|
61
|
+
//
|
|
62
|
+
// The captures spread into a plain object (`{ ...(await import()) }`) to freeze
|
|
63
|
+
// the real exports by value. A module-namespace reference is a live view:
|
|
64
|
+
// `mock.module` mutates it in place, so a bare `await import` would itself
|
|
65
|
+
// return the stub once the stub is registered, and `afterAll` would "restore"
|
|
66
|
+
// the stub instead of the real module.
|
|
67
|
+
const actualAnalyzeConversation = {
|
|
68
|
+
...(await import("../analyze-conversation.js")),
|
|
69
|
+
};
|
|
70
|
+
const actualAutoAnalysisEnqueue = {
|
|
71
|
+
...(await import("../auto-analysis-enqueue.js")),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
beforeAll(() => {
|
|
75
|
+
mock.module("../analyze-conversation.js", () => ({
|
|
76
|
+
...actualAnalyzeConversation,
|
|
77
|
+
analyzeConversation: mockAnalyzeConversation,
|
|
78
|
+
}));
|
|
79
|
+
mock.module("../auto-analysis-enqueue.js", () => ({
|
|
80
|
+
...actualAutoAnalysisEnqueue,
|
|
81
|
+
enqueueAutoAnalysisIfEnabled: mockEnqueueAutoAnalysisIfEnabled,
|
|
82
|
+
}));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterAll(() => {
|
|
86
|
+
mock.module("../analyze-conversation.js", () => actualAnalyzeConversation);
|
|
87
|
+
mock.module("../auto-analysis-enqueue.js", () => actualAutoAnalysisEnqueue);
|
|
88
|
+
});
|
|
54
89
|
|
|
55
90
|
import { DEFAULT_CONFIG } from "../../../config/defaults.js";
|
|
56
91
|
import type { AssistantConfig } from "../../../config/types.js";
|
|
@@ -45,6 +45,7 @@ function makeConversationRow(
|
|
|
45
45
|
archivedAt: null,
|
|
46
46
|
surfacedAt: null,
|
|
47
47
|
inferenceProfile: null,
|
|
48
|
+
enabledPlugins: null,
|
|
48
49
|
inferenceProfileSessionId: null,
|
|
49
50
|
inferenceProfileExpiresAt: null,
|
|
50
51
|
lastNotifiedInferenceProfile: null,
|
|
@@ -139,3 +140,22 @@ describe("serializeConversationSummary · surfaced groupId normalization", () =>
|
|
|
139
140
|
);
|
|
140
141
|
});
|
|
141
142
|
});
|
|
143
|
+
|
|
144
|
+
describe("serializeConversationSummary · enabledPlugins", () => {
|
|
145
|
+
test("serializes a non-empty plugin scope", () => {
|
|
146
|
+
const summary = serialize(
|
|
147
|
+
makeConversationRow({ enabledPlugins: ["plugin-a", "plugin-b"] }),
|
|
148
|
+
);
|
|
149
|
+
expect(summary.enabledPlugins).toEqual(["plugin-a", "plugin-b"]);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("preserves an explicit empty scope (user cleared all optional plugins)", () => {
|
|
153
|
+
const summary = serialize(makeConversationRow({ enabledPlugins: [] }));
|
|
154
|
+
expect(summary.enabledPlugins).toEqual([]);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("omits the field when there is no per-chat restriction (null)", () => {
|
|
158
|
+
const summary = serialize(makeConversationRow({ enabledPlugins: null }));
|
|
159
|
+
expect("enabledPlugins" in summary).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -232,12 +232,19 @@ export async function analyzeConversation(
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// i. Persist the user message (with provenance snapshot matching the
|
|
235
|
-
// trust context we will run under).
|
|
235
|
+
// trust context we will run under). Mint the request ID up front and
|
|
236
|
+
// persist the row under it so the analysis prompt's row id and the
|
|
237
|
+
// turn's `currentRequestId` are the same value: the same
|
|
238
|
+
// requestId-as-row-id invariant the standard submit path holds. Without
|
|
239
|
+
// this, `addMessage` would auto-assign a fresh row id while step (k)
|
|
240
|
+
// minted an unrelated `currentRequestId`, leaving `userMessageId` and
|
|
241
|
+
// `requestId` divergent for the analysis turn.
|
|
242
|
+
const requestId = crypto.randomUUID();
|
|
236
243
|
const message = await addMessage(
|
|
237
244
|
analysisConversationId,
|
|
238
245
|
"user",
|
|
239
246
|
JSON.stringify([{ type: "text", text: prompt }]),
|
|
240
|
-
{ metadata: { provenanceTrustClass: trustClass } },
|
|
247
|
+
{ id: requestId, metadata: { provenanceTrustClass: trustClass } },
|
|
241
248
|
);
|
|
242
249
|
const messageId = message.id;
|
|
243
250
|
|
|
@@ -268,10 +275,13 @@ export async function analyzeConversation(
|
|
|
268
275
|
// j. Wire broadcastMessage as the event publisher
|
|
269
276
|
analysisConversation.updateClient(broadcastMessage, !hasLiveSubscriber);
|
|
270
277
|
|
|
271
|
-
// k. Set up processing state (required by runAgentLoop guard)
|
|
278
|
+
// k. Set up processing state (required by runAgentLoop guard). Reuse the
|
|
279
|
+
// request ID the prompt row was persisted under (step i) so
|
|
280
|
+
// `currentRequestId` equals the user message's row id, keeping
|
|
281
|
+
// `requestId === userMessageId` for the analysis turn.
|
|
272
282
|
analysisConversation.setProcessing(true);
|
|
273
283
|
analysisConversation.abortController = new AbortController();
|
|
274
|
-
analysisConversation.currentRequestId =
|
|
284
|
+
analysisConversation.currentRequestId = requestId;
|
|
275
285
|
|
|
276
286
|
// l. Fire-and-forget the agent loop. `callSite: 'analyzeConversation'`
|
|
277
287
|
// routes the per-call provider config through `resolveCallSiteConfig`
|
|
@@ -215,6 +215,11 @@ export function serializeConversationSummary(params: {
|
|
|
215
215
|
...(conversation.inferenceProfile != null
|
|
216
216
|
? { inferenceProfile: conversation.inferenceProfile }
|
|
217
217
|
: {}),
|
|
218
|
+
// Include when non-null so an explicit `[]` (user cleared all plugins) is
|
|
219
|
+
// preserved; `null`/default is omitted.
|
|
220
|
+
...(conversation.enabledPlugins != null
|
|
221
|
+
? { enabledPlugins: conversation.enabledPlugins }
|
|
222
|
+
: {}),
|
|
218
223
|
isProcessing,
|
|
219
224
|
};
|
|
220
225
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assistant emits a `<no_response/>` sentinel to signal that a turn should
|
|
3
|
+
* produce no user-visible reply. Slack surfaces that begin work on the first
|
|
4
|
+
* deliverable text (the thinking-status indicator and native reply streaming)
|
|
5
|
+
* must not act on a partially-arrived sentinel: a slow stream can surface just
|
|
6
|
+
* `<` or `<no_resp` before the rest lands, and starting on that leaks a stray
|
|
7
|
+
* message that later resolves to empty.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Matches a message whose entire content is the sentinel. */
|
|
11
|
+
const NO_RESPONSE_ONLY_RE = /^\s*<no_response\s*\/?>\s*$/i;
|
|
12
|
+
|
|
13
|
+
/** Matches every sentinel occurrence for stripping it out of mixed content. */
|
|
14
|
+
export const NO_RESPONSE_INLINE_RE = /<no_response\s*\/?>/gi;
|
|
15
|
+
|
|
16
|
+
const NO_RESPONSE_SENTINEL_FORMS = [
|
|
17
|
+
"<no_response/>",
|
|
18
|
+
"<no_response />",
|
|
19
|
+
"<no_response>",
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Whether `text` could still grow into the sentinel — i.e. it is a leading
|
|
24
|
+
* substring of one of its forms. Holding on these keeps a slowly-streamed
|
|
25
|
+
* `<no_response/>` from surfacing as visible partial content.
|
|
26
|
+
*/
|
|
27
|
+
function isPotentialNoResponsePrefix(text: string): boolean {
|
|
28
|
+
const lower = text.trim().toLowerCase();
|
|
29
|
+
if (lower.length === 0) return false;
|
|
30
|
+
return NO_RESPONSE_SENTINEL_FORMS.some((sentinel) =>
|
|
31
|
+
sentinel.startsWith(lower),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether `text` carries user-visible content worth acting on now. Returns
|
|
37
|
+
* `false` for empty text, the standalone sentinel, and any prefix that could
|
|
38
|
+
* still complete into one; returns `true` once real content remains after
|
|
39
|
+
* stripping inline sentinels.
|
|
40
|
+
*/
|
|
41
|
+
export function hasDeliverableAssistantText(text: string): boolean {
|
|
42
|
+
const trimmed = text.trim();
|
|
43
|
+
if (trimmed.length === 0) return false;
|
|
44
|
+
if (NO_RESPONSE_ONLY_RE.test(trimmed)) return false;
|
|
45
|
+
if (isPotentialNoResponsePrefix(trimmed)) return false;
|
|
46
|
+
return trimmed.replace(NO_RESPONSE_INLINE_RE, "").trim().length > 0;
|
|
47
|
+
}
|