@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
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { refreshBackgroundWakeIntent } from "../background-wake/publisher.js";
|
|
1
2
|
import { getConfig } from "../config/loader.js";
|
|
2
3
|
import {
|
|
3
4
|
checkDiskPressureBackgroundGate,
|
|
4
5
|
diskPressureBackgroundSkipLogFields,
|
|
5
6
|
shouldLogDiskPressureBackgroundSkip,
|
|
6
7
|
} from "../daemon/disk-pressure-background-gate.js";
|
|
8
|
+
import { processMessage } from "../daemon/process-message.js";
|
|
7
9
|
import { INTERNAL_GUARDIAN_TRUST_CONTEXT } from "../daemon/trust-context.js";
|
|
8
10
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
9
11
|
import { bootstrapConversation } from "../persistence/conversation-bootstrap.js";
|
|
@@ -16,7 +18,7 @@ import { publishConversationListChanged } from "../runtime/sync/resource-sync-ev
|
|
|
16
18
|
import { runSequencesOnce } from "../sequence/engine.js";
|
|
17
19
|
import { areCoreToolsInitialized } from "../tools/registry.js";
|
|
18
20
|
import { getLogger } from "../util/logger.js";
|
|
19
|
-
import { runWatchersOnce
|
|
21
|
+
import { runWatchersOnce } from "../watcher/engine.js";
|
|
20
22
|
import { normalizeCapabilityManifest } from "../workflows/capabilities.js";
|
|
21
23
|
import { getWorkflowRunManager } from "../workflows/run-manager.js";
|
|
22
24
|
import { hasSetConstructs } from "./recurrence-engine.js";
|
|
@@ -38,28 +40,48 @@ import {
|
|
|
38
40
|
scheduleRetry,
|
|
39
41
|
setScheduleRunConversationId,
|
|
40
42
|
} from "./schedule-store.js";
|
|
43
|
+
import {
|
|
44
|
+
startScheduleWorkerIfEnabled,
|
|
45
|
+
stopScheduleWorker,
|
|
46
|
+
} from "./worker-control.js";
|
|
41
47
|
|
|
42
48
|
const log = getLogger("scheduler");
|
|
43
49
|
|
|
44
|
-
import type {
|
|
45
|
-
type ScheduleNotifyModeNotifier = (payload: {
|
|
46
|
-
id: string;
|
|
47
|
-
label: string;
|
|
48
|
-
message: string;
|
|
49
|
-
routingIntent: RoutingIntent;
|
|
50
|
-
routingHints: Record<string, unknown>;
|
|
51
|
-
}) => void | Promise<void>;
|
|
52
|
-
|
|
53
|
-
type ScheduleConversationCreatedNotifier = (info: {
|
|
54
|
-
conversationId: string;
|
|
55
|
-
scheduleJobId: string;
|
|
56
|
-
title: string;
|
|
57
|
-
}) => void;
|
|
50
|
+
import type { ScheduleMessageOptions } from "./scheduler-types.js";
|
|
58
51
|
|
|
59
52
|
/**
|
|
60
|
-
*
|
|
61
|
-
* `
|
|
53
|
+
* Run a scheduled message through the daemon's agent pipeline, translating the
|
|
54
|
+
* schedule's `trustClass` into the trust context `processMessage` expects.
|
|
62
55
|
*/
|
|
56
|
+
async function dispatchScheduleMessage(
|
|
57
|
+
conversationId: string,
|
|
58
|
+
message: string,
|
|
59
|
+
options?: ScheduleMessageOptions,
|
|
60
|
+
): Promise<void> {
|
|
61
|
+
await processMessage(
|
|
62
|
+
conversationId,
|
|
63
|
+
message,
|
|
64
|
+
options
|
|
65
|
+
? {
|
|
66
|
+
...(options.trustClass
|
|
67
|
+
? {
|
|
68
|
+
trustContext: {
|
|
69
|
+
sourceChannel: "vellum",
|
|
70
|
+
trustClass: options.trustClass,
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
: {}),
|
|
74
|
+
...(options.taskRunId ? { taskRunId: options.taskRunId } : {}),
|
|
75
|
+
...(options.overrideProfile
|
|
76
|
+
? { overrideProfile: options.overrideProfile }
|
|
77
|
+
: {}),
|
|
78
|
+
...(options.cronRunId ? { cronRunId: options.cronRunId } : {}),
|
|
79
|
+
}
|
|
80
|
+
: undefined,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Emit the attention signal for a `notify`-mode schedule firing. */
|
|
63
85
|
async function emitScheduleNotifySignal(payload: {
|
|
64
86
|
id: string;
|
|
65
87
|
label: string;
|
|
@@ -198,40 +220,23 @@ async function handleExecutionFailure(params: {
|
|
|
198
220
|
/** The running scheduler, retained so shutdown can stop it. */
|
|
199
221
|
let instance: SchedulerHandle | null = null;
|
|
200
222
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
void import("../background-wake/publisher.js")
|
|
208
|
-
.then(({ refreshBackgroundWakeIntent }) =>
|
|
209
|
-
refreshBackgroundWakeIntent(reason),
|
|
210
|
-
)
|
|
211
|
-
.catch((err) =>
|
|
212
|
-
log.warn({ err, reason }, "Failed to queue background wake refresh"),
|
|
213
|
-
);
|
|
214
|
-
}
|
|
223
|
+
export function startScheduler(): SchedulerHandle {
|
|
224
|
+
// When the schedule worker owns schedule execution, spawn it now as a child
|
|
225
|
+
// of the daemon so it is running immediately. Fire-and-forget — a worker
|
|
226
|
+
// failure must never block boot, and every tick below re-reads the flag so
|
|
227
|
+
// ownership stays consistent either way.
|
|
228
|
+
startScheduleWorkerIfEnabled();
|
|
215
229
|
|
|
216
|
-
export function startScheduler(
|
|
217
|
-
processMessage: ScheduleMessageProcessor,
|
|
218
|
-
notifyScheduleOneShot: ScheduleNotifyModeNotifier = emitScheduleNotifySignal,
|
|
219
|
-
watcherNotifier: WatcherNotifier = emitWatcherNotifySignal,
|
|
220
|
-
onScheduleConversationCreated: ScheduleConversationCreatedNotifier = broadcastScheduleConversationCreated,
|
|
221
|
-
): SchedulerHandle {
|
|
222
230
|
let stopped = false;
|
|
223
231
|
let tickRunning = false;
|
|
224
232
|
|
|
225
233
|
const tick = async () => {
|
|
226
|
-
if (stopped || tickRunning)
|
|
234
|
+
if (stopped || tickRunning) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
227
237
|
tickRunning = true;
|
|
228
238
|
try {
|
|
229
|
-
await runScheduleOnce(
|
|
230
|
-
processMessage,
|
|
231
|
-
notifyScheduleOneShot,
|
|
232
|
-
watcherNotifier,
|
|
233
|
-
onScheduleConversationCreated,
|
|
234
|
-
);
|
|
239
|
+
await runScheduleOnce();
|
|
235
240
|
} catch (err) {
|
|
236
241
|
log.error({ err }, "Schedule tick failed");
|
|
237
242
|
} finally {
|
|
@@ -247,23 +252,12 @@ export function startScheduler(
|
|
|
247
252
|
|
|
248
253
|
instance = {
|
|
249
254
|
async runOnce(): Promise<number> {
|
|
250
|
-
return runScheduleOnce(
|
|
251
|
-
processMessage,
|
|
252
|
-
notifyScheduleOneShot,
|
|
253
|
-
watcherNotifier,
|
|
254
|
-
onScheduleConversationCreated,
|
|
255
|
-
);
|
|
255
|
+
return runScheduleOnce();
|
|
256
256
|
},
|
|
257
257
|
async runDueWorkOnce(
|
|
258
258
|
options?: SchedulerRunDueWorkOptions,
|
|
259
259
|
): Promise<SchedulerDueWorkResult> {
|
|
260
|
-
return runScheduleDueWorkOnce(
|
|
261
|
-
processMessage,
|
|
262
|
-
notifyScheduleOneShot,
|
|
263
|
-
watcherNotifier,
|
|
264
|
-
onScheduleConversationCreated,
|
|
265
|
-
options,
|
|
266
|
-
);
|
|
260
|
+
return runScheduleDueWorkOnce(options);
|
|
267
261
|
},
|
|
268
262
|
stop(): void {
|
|
269
263
|
stopped = true;
|
|
@@ -273,14 +267,22 @@ export function startScheduler(
|
|
|
273
267
|
|
|
274
268
|
// Publish the initial background wake intent now that the scheduler is live
|
|
275
269
|
// and its schedules are visible to `computeNextBackgroundWakeIntent`.
|
|
276
|
-
|
|
270
|
+
refreshBackgroundWakeIntent("daemon-startup");
|
|
277
271
|
|
|
278
272
|
return instance;
|
|
279
273
|
}
|
|
280
274
|
|
|
281
|
-
/**
|
|
275
|
+
/**
|
|
276
|
+
* Stop the running scheduler if one was started, and SIGTERM the schedule
|
|
277
|
+
* worker process if one is running. The worker stop is keyed off live state
|
|
278
|
+
* rather than config: it may have been spawned at startup or out of band via
|
|
279
|
+
* `assistant schedules worker start`.
|
|
280
|
+
*/
|
|
282
281
|
export function stopScheduler(): void {
|
|
283
|
-
|
|
282
|
+
stopScheduleWorker();
|
|
283
|
+
if (!instance) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
284
286
|
instance.stop();
|
|
285
287
|
instance = null;
|
|
286
288
|
}
|
|
@@ -290,30 +292,36 @@ export function getScheduler(): SchedulerHandle | null {
|
|
|
290
292
|
return instance;
|
|
291
293
|
}
|
|
292
294
|
|
|
293
|
-
export async function runScheduleOnce(
|
|
294
|
-
|
|
295
|
-
notifyScheduleOneShot: ScheduleNotifyModeNotifier,
|
|
296
|
-
watcherNotifier?: WatcherNotifier,
|
|
297
|
-
onScheduleConversationCreated?: ScheduleConversationCreatedNotifier,
|
|
298
|
-
): Promise<number> {
|
|
299
|
-
const result = await runScheduleDueWorkOnce(
|
|
300
|
-
processMessage,
|
|
301
|
-
notifyScheduleOneShot,
|
|
302
|
-
watcherNotifier,
|
|
303
|
-
onScheduleConversationCreated,
|
|
304
|
-
);
|
|
295
|
+
export async function runScheduleOnce(): Promise<number> {
|
|
296
|
+
const result = await runScheduleDueWorkOnce();
|
|
305
297
|
return result.completed + result.failed + result.skipped;
|
|
306
298
|
}
|
|
307
299
|
|
|
300
|
+
/**
|
|
301
|
+
* True while the schedule worker process owns schedule execution. Read from
|
|
302
|
+
* config on every call so a runtime `assistant schedules worker start`/`stop`
|
|
303
|
+
* switches ownership without a restart.
|
|
304
|
+
*/
|
|
305
|
+
function scheduleWorkerOwnsSchedules(): boolean {
|
|
306
|
+
return getConfig().schedules?.worker?.enabled === true;
|
|
307
|
+
}
|
|
308
|
+
|
|
308
309
|
export async function runScheduleDueWorkOnce(
|
|
309
|
-
processMessage: ScheduleMessageProcessor,
|
|
310
|
-
notifyScheduleOneShot: ScheduleNotifyModeNotifier,
|
|
311
|
-
watcherNotifier?: WatcherNotifier,
|
|
312
|
-
onScheduleConversationCreated?: ScheduleConversationCreatedNotifier,
|
|
313
310
|
options: SchedulerRunDueWorkOptions = {},
|
|
314
311
|
): Promise<SchedulerDueWorkResult> {
|
|
315
312
|
const now = options.now ?? Date.now();
|
|
316
313
|
const minStartBudgetMs = options.minStartBudgetMs ?? 0;
|
|
314
|
+
// While `schedules.worker.enabled` is set, the schedule worker process owns
|
|
315
|
+
// schedule execution: this process leaves every due schedule unclaimed so
|
|
316
|
+
// exactly one process runs them, and reports none of them as its own
|
|
317
|
+
// pending work. The flag is re-read from config every tick, so `assistant
|
|
318
|
+
// schedules worker start`/`stop` switch ownership without a restart.
|
|
319
|
+
// Watchers and sequences below always run in the daemon.
|
|
320
|
+
const workerOwnsSchedules = scheduleWorkerOwnsSchedules();
|
|
321
|
+
const countStillPending = (at: number): number =>
|
|
322
|
+
options.includeStillPending && !workerOwnsSchedules
|
|
323
|
+
? countDueScheduleJobs(at)
|
|
324
|
+
: 0;
|
|
317
325
|
const result: SchedulerDueWorkResult = {
|
|
318
326
|
claimed: 0,
|
|
319
327
|
completed: 0,
|
|
@@ -321,17 +329,12 @@ export async function runScheduleDueWorkOnce(
|
|
|
321
329
|
skipped: 0,
|
|
322
330
|
stillPending: 0,
|
|
323
331
|
};
|
|
324
|
-
const mark = (status: "completed" | "failed" | "skipped") => {
|
|
325
|
-
result[status] += 1;
|
|
326
|
-
};
|
|
327
332
|
|
|
328
333
|
if (
|
|
329
334
|
options.deadlineAt != null &&
|
|
330
335
|
options.deadlineAt - Date.now() < minStartBudgetMs
|
|
331
336
|
) {
|
|
332
|
-
result.stillPending =
|
|
333
|
-
? countDueScheduleJobs(now)
|
|
334
|
-
: 0;
|
|
337
|
+
result.stillPending = countStillPending(now);
|
|
335
338
|
result.skipped = result.stillPending;
|
|
336
339
|
return result;
|
|
337
340
|
}
|
|
@@ -347,13 +350,73 @@ export async function runScheduleDueWorkOnce(
|
|
|
347
350
|
"Schedule tick skipped during disk pressure cleanup mode",
|
|
348
351
|
);
|
|
349
352
|
}
|
|
350
|
-
result.stillPending =
|
|
351
|
-
? countDueScheduleJobs(now)
|
|
352
|
-
: 0;
|
|
353
|
+
result.stillPending = countStillPending(now);
|
|
353
354
|
return result;
|
|
354
355
|
}
|
|
355
356
|
|
|
356
357
|
// ── Schedules (recurring cron/RRULE + one-shot) ─────────────────────
|
|
358
|
+
if (!workerOwnsSchedules) {
|
|
359
|
+
const schedules = await runDueSchedulesOnce(now);
|
|
360
|
+
result.claimed = schedules.claimed;
|
|
361
|
+
result.completed += schedules.completed;
|
|
362
|
+
result.failed += schedules.failed;
|
|
363
|
+
result.skipped += schedules.skipped;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ── Watchers (event-driven polling) ────────────────────────────────
|
|
367
|
+
try {
|
|
368
|
+
const watcherProcessed = await runWatchersOnce(emitWatcherNotifySignal);
|
|
369
|
+
result.completed += watcherProcessed;
|
|
370
|
+
} catch (err) {
|
|
371
|
+
log.error({ err }, "Watcher tick failed");
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ── Sequences (multi-step outreach) ──────────────────────────────
|
|
375
|
+
try {
|
|
376
|
+
const sequenceProcessed = await runSequencesOnce();
|
|
377
|
+
result.completed += sequenceProcessed;
|
|
378
|
+
} catch (err) {
|
|
379
|
+
log.error({ err }, "Sequence engine tick failed");
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
result.stillPending = countStillPending(Date.now());
|
|
383
|
+
const processed = result.completed + result.failed + result.skipped;
|
|
384
|
+
if (processed > 0) {
|
|
385
|
+
log.info({ processed }, "Schedule tick complete");
|
|
386
|
+
}
|
|
387
|
+
return result;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Claim and execute every due schedule (all modes: notify, script, wake,
|
|
392
|
+
* workflow, execute). Called from the daemon's tick while
|
|
393
|
+
* `schedules.worker.enabled` is off, and from the schedule worker process's
|
|
394
|
+
* tick while it is on. Claims are atomic in the schedule store, so a process
|
|
395
|
+
* whose view of the flag lags a tick behind cannot double-run a job another
|
|
396
|
+
* process already claimed.
|
|
397
|
+
*/
|
|
398
|
+
export async function runDueSchedulesOnce(
|
|
399
|
+
now: number = Date.now(),
|
|
400
|
+
): Promise<Omit<SchedulerDueWorkResult, "stillPending">> {
|
|
401
|
+
const result = { claimed: 0, completed: 0, failed: 0, skipped: 0 };
|
|
402
|
+
const mark = (status: "completed" | "failed" | "skipped") => {
|
|
403
|
+
result[status] += 1;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const diskPressureGate = checkDiskPressureBackgroundGate("background-work");
|
|
407
|
+
if (diskPressureGate.action === "skip") {
|
|
408
|
+
if (shouldLogDiskPressureBackgroundSkip("scheduler-schedules")) {
|
|
409
|
+
log.warn(
|
|
410
|
+
{
|
|
411
|
+
source: "schedule",
|
|
412
|
+
...diskPressureBackgroundSkipLogFields(diskPressureGate),
|
|
413
|
+
},
|
|
414
|
+
"Due-schedule run skipped during disk pressure cleanup mode",
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
|
|
357
420
|
const jobs = await claimDueSchedules(now);
|
|
358
421
|
result.claimed = jobs.length;
|
|
359
422
|
for (const job of jobs) {
|
|
@@ -367,7 +430,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
367
430
|
{ jobId: job.id, name: job.name, isOneShot },
|
|
368
431
|
"Firing schedule notification",
|
|
369
432
|
);
|
|
370
|
-
await
|
|
433
|
+
await emitScheduleNotifySignal({
|
|
371
434
|
id: job.id,
|
|
372
435
|
label: job.name,
|
|
373
436
|
message: job.message,
|
|
@@ -428,6 +491,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
428
491
|
const result: ScriptResult = await runScript(job.script, {
|
|
429
492
|
timeoutMs: job.timeoutMs ?? undefined,
|
|
430
493
|
scheduleRunId: runId,
|
|
494
|
+
scheduleId: job.id,
|
|
431
495
|
});
|
|
432
496
|
await completeScheduleRun(runId, {
|
|
433
497
|
status: result.exitCode === 0 ? "ok" : "error",
|
|
@@ -435,7 +499,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
435
499
|
error: result.stderr || undefined,
|
|
436
500
|
});
|
|
437
501
|
if (result.exitCode === 0) {
|
|
438
|
-
if (isOneShot)
|
|
502
|
+
if (isOneShot) {
|
|
503
|
+
await completeOneShot(job.id);
|
|
504
|
+
}
|
|
439
505
|
} else {
|
|
440
506
|
const errorMsg =
|
|
441
507
|
result.stderr || "Script exited with non-zero status";
|
|
@@ -464,7 +530,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
464
530
|
{ jobId: job.id, name: job.name },
|
|
465
531
|
"Wake schedule missing wakeConversationId — completing as no-op",
|
|
466
532
|
);
|
|
467
|
-
if (isOneShot)
|
|
533
|
+
if (isOneShot) {
|
|
534
|
+
await completeOneShot(job.id);
|
|
535
|
+
}
|
|
468
536
|
mark("skipped");
|
|
469
537
|
continue;
|
|
470
538
|
}
|
|
@@ -528,7 +596,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
528
596
|
},
|
|
529
597
|
"Wake not invoked; skipping feed event",
|
|
530
598
|
);
|
|
531
|
-
if (isOneShot)
|
|
599
|
+
if (isOneShot) {
|
|
600
|
+
await completeOneShot(job.id);
|
|
601
|
+
}
|
|
532
602
|
mark("skipped");
|
|
533
603
|
continue;
|
|
534
604
|
}
|
|
@@ -626,7 +696,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
626
696
|
status: "ok",
|
|
627
697
|
output: `workflow run ${workflowRunId} started`,
|
|
628
698
|
});
|
|
629
|
-
if (isOneShot)
|
|
699
|
+
if (isOneShot) {
|
|
700
|
+
await completeOneShot(job.id);
|
|
701
|
+
}
|
|
630
702
|
} catch (err) {
|
|
631
703
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
632
704
|
log.warn(
|
|
@@ -675,7 +747,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
675
747
|
scheduleJobId: job.id,
|
|
676
748
|
},
|
|
677
749
|
async (conversationId, message, taskRunId) => {
|
|
678
|
-
await
|
|
750
|
+
await dispatchScheduleMessage(conversationId, message, {
|
|
679
751
|
trustClass: "guardian",
|
|
680
752
|
taskRunId,
|
|
681
753
|
cronRunId: runId,
|
|
@@ -687,7 +759,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
687
759
|
);
|
|
688
760
|
|
|
689
761
|
await setScheduleRunConversationId(runId, result.conversationId);
|
|
690
|
-
|
|
762
|
+
broadcastScheduleConversationCreated({
|
|
691
763
|
conversationId: result.conversationId,
|
|
692
764
|
scheduleJobId: job.id,
|
|
693
765
|
title: result.status === "failed" ? `${job.name}: Error` : job.name,
|
|
@@ -712,7 +784,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
712
784
|
failed = true;
|
|
713
785
|
} else {
|
|
714
786
|
await completeScheduleRun(runId, { status: "ok" });
|
|
715
|
-
if (isOneShot)
|
|
787
|
+
if (isOneShot) {
|
|
788
|
+
await completeOneShot(job.id);
|
|
789
|
+
}
|
|
716
790
|
}
|
|
717
791
|
} catch (err) {
|
|
718
792
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -738,7 +812,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
738
812
|
origin: "schedule",
|
|
739
813
|
systemHint: `Schedule: ${job.name}`,
|
|
740
814
|
});
|
|
741
|
-
|
|
815
|
+
broadcastScheduleConversationCreated({
|
|
742
816
|
conversationId: fallbackConversation.id,
|
|
743
817
|
scheduleJobId: job.id,
|
|
744
818
|
title: `${job.name}: Error`,
|
|
@@ -801,18 +875,18 @@ export async function runScheduleDueWorkOnce(
|
|
|
801
875
|
const runId = await createScheduleRun(job.id, reusedConversationId);
|
|
802
876
|
|
|
803
877
|
if (reusedConversationId) {
|
|
804
|
-
// Reuse path:
|
|
805
|
-
//
|
|
806
|
-
//
|
|
807
|
-
//
|
|
878
|
+
// Reuse path: dispatch the message into the existing conversation so it
|
|
879
|
+
// is continued in place. `runBackgroundJob` unconditionally bootstraps a
|
|
880
|
+
// new conversation and is therefore not a drop-in replacement for the
|
|
881
|
+
// reuse semantics.
|
|
808
882
|
conversationId = reusedConversationId;
|
|
809
|
-
|
|
883
|
+
broadcastScheduleConversationCreated({
|
|
810
884
|
conversationId,
|
|
811
885
|
scheduleJobId: job.id,
|
|
812
886
|
title: job.name,
|
|
813
887
|
});
|
|
814
888
|
try {
|
|
815
|
-
await
|
|
889
|
+
await dispatchScheduleMessage(conversationId, job.message, {
|
|
816
890
|
trustClass: "guardian",
|
|
817
891
|
cronRunId: runId,
|
|
818
892
|
...(job.inferenceProfile
|
|
@@ -854,7 +928,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
854
928
|
onConversationCreated: async (newConversationId) => {
|
|
855
929
|
runConversationId = newConversationId;
|
|
856
930
|
await setScheduleRunConversationId(runId, newConversationId);
|
|
857
|
-
|
|
931
|
+
broadcastScheduleConversationCreated({
|
|
858
932
|
conversationId: newConversationId,
|
|
859
933
|
scheduleJobId: job.id,
|
|
860
934
|
title: job.name,
|
|
@@ -880,7 +954,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
880
954
|
|
|
881
955
|
if (ok) {
|
|
882
956
|
await completeScheduleRun(runId, { status: "ok" });
|
|
883
|
-
if (isOneShot)
|
|
957
|
+
if (isOneShot) {
|
|
958
|
+
await completeOneShot(job.id);
|
|
959
|
+
}
|
|
884
960
|
mark("completed");
|
|
885
961
|
} else {
|
|
886
962
|
log.warn(
|
|
@@ -923,31 +999,6 @@ export async function runScheduleDueWorkOnce(
|
|
|
923
999
|
}
|
|
924
1000
|
}
|
|
925
1001
|
|
|
926
|
-
// ── Watchers (event-driven polling) ────────────────────────────────
|
|
927
|
-
if (watcherNotifier) {
|
|
928
|
-
try {
|
|
929
|
-
const watcherProcessed = await runWatchersOnce(watcherNotifier);
|
|
930
|
-
result.completed += watcherProcessed;
|
|
931
|
-
} catch (err) {
|
|
932
|
-
log.error({ err }, "Watcher tick failed");
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
// ── Sequences (multi-step outreach) ──────────────────────────────
|
|
937
|
-
try {
|
|
938
|
-
const sequenceProcessed = await runSequencesOnce();
|
|
939
|
-
result.completed += sequenceProcessed;
|
|
940
|
-
} catch (err) {
|
|
941
|
-
log.error({ err }, "Sequence engine tick failed");
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
if (options.includeStillPending) {
|
|
945
|
-
result.stillPending = countDueScheduleJobs(Date.now());
|
|
946
|
-
}
|
|
947
|
-
const processed = result.completed + result.failed + result.skipped;
|
|
948
|
-
if (processed > 0) {
|
|
949
|
-
log.info({ processed }, "Schedule tick complete");
|
|
950
|
-
}
|
|
951
1002
|
return result;
|
|
952
1003
|
}
|
|
953
1004
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared control surface for the schedule worker *process* — the background OS
|
|
3
|
+
* process whose entry point is `worker.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Both the `assistant schedules worker` CLI and the daemon lifecycle (when
|
|
6
|
+
* `schedules.worker.enabled` is set) need to probe, spawn, and stop this
|
|
7
|
+
* process. The generic PID-file mechanics live in `util/worker-process.ts`;
|
|
8
|
+
* this module binds them to the schedule worker's PID path and entry point.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { getConfig } from "../config/loader.js";
|
|
12
|
+
import { getLogger } from "../util/logger.js";
|
|
13
|
+
import { getScheduleWorkerPidPath } from "../util/platform.js";
|
|
14
|
+
import {
|
|
15
|
+
probeWorkerPidFile,
|
|
16
|
+
spawnWorkerProcess,
|
|
17
|
+
type SpawnWorkerProcessOptions,
|
|
18
|
+
stopWorkerProcess,
|
|
19
|
+
WorkerProcessSpawnError,
|
|
20
|
+
type WorkerProcessStatus,
|
|
21
|
+
} from "../util/worker-process.js";
|
|
22
|
+
|
|
23
|
+
const log = getLogger("schedule-worker-control");
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Inspect the PID file to determine whether the schedule worker process is
|
|
27
|
+
* alive. A stale PID file (pointing at a dead process) is cleaned up and
|
|
28
|
+
* reported as not_running.
|
|
29
|
+
*/
|
|
30
|
+
export function probeScheduleWorker(): WorkerProcessStatus {
|
|
31
|
+
return probeWorkerPidFile(getScheduleWorkerPidPath());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class ScheduleWorkerSpawnError extends WorkerProcessSpawnError {}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Spawn the schedule worker as a background process. If a worker is already
|
|
38
|
+
* running, returns its PID with `alreadyRunning: true` rather than spawning a
|
|
39
|
+
* second one. Throws {@link ScheduleWorkerSpawnError} if the child crashes
|
|
40
|
+
* during startup or never writes its PID file within the wait window.
|
|
41
|
+
*
|
|
42
|
+
* Beyond the generic option semantics documented on
|
|
43
|
+
* {@link SpawnWorkerProcessOptions}: callers whose failure path leaves
|
|
44
|
+
* `schedules.worker.enabled` off (the start route) should set
|
|
45
|
+
* `terminateOnTimeout` so a worker reported as failed cannot come up later
|
|
46
|
+
* and run schedules alongside the daemon's scheduler; the daemon's boot
|
|
47
|
+
* spawn leaves the flag on, so a late worker there is the desired sole
|
|
48
|
+
* schedule runner and passes `false`.
|
|
49
|
+
*/
|
|
50
|
+
export async function spawnScheduleWorkerProcess(
|
|
51
|
+
opts: SpawnWorkerProcessOptions = {},
|
|
52
|
+
): Promise<{ pid: number; alreadyRunning: boolean }> {
|
|
53
|
+
try {
|
|
54
|
+
return await spawnWorkerProcess({
|
|
55
|
+
pidPath: getScheduleWorkerPidPath(),
|
|
56
|
+
entry: new URL("./worker.ts", import.meta.url),
|
|
57
|
+
workerLabel: "Schedule worker",
|
|
58
|
+
options: opts,
|
|
59
|
+
});
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err instanceof WorkerProcessSpawnError) {
|
|
62
|
+
throw new ScheduleWorkerSpawnError(err.message);
|
|
63
|
+
}
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Send SIGTERM to the schedule worker process if it is actually running.
|
|
70
|
+
* Returns the status observed before signalling. Only throws if
|
|
71
|
+
* `process.kill` itself fails (e.g. EPERM) — a not-running worker is a no-op.
|
|
72
|
+
*/
|
|
73
|
+
export function stopScheduleWorkerProcess(): WorkerProcessStatus {
|
|
74
|
+
return stopWorkerProcess(getScheduleWorkerPidPath());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Daemon-lifecycle entry point: spawn the schedule worker as a child of the
|
|
79
|
+
* daemon (`detached: false`, so it appears in `assistant ps` and is torn down
|
|
80
|
+
* on shutdown) when `schedules.worker.enabled` is set. Fire-and-forget — a
|
|
81
|
+
* worker failure must never block boot. The flag stays on either way, so a
|
|
82
|
+
* worker that comes up late is the desired sole schedule runner
|
|
83
|
+
* (`terminateOnTimeout` is deliberately not set).
|
|
84
|
+
*/
|
|
85
|
+
export function startScheduleWorkerIfEnabled(): void {
|
|
86
|
+
if (getConfig().schedules?.worker?.enabled !== true) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
void spawnScheduleWorkerProcess({ detached: false })
|
|
90
|
+
.then((r) =>
|
|
91
|
+
log.info(
|
|
92
|
+
{ pid: r.pid, alreadyRunning: r.alreadyRunning },
|
|
93
|
+
r.alreadyRunning
|
|
94
|
+
? "Schedule worker process already running — reusing it"
|
|
95
|
+
: "Schedule worker process started at boot",
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
.catch((err) =>
|
|
99
|
+
log.warn({ err }, "Failed to start schedule worker at boot"),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Daemon-lifecycle entry point: SIGTERM the schedule worker process if it is
|
|
105
|
+
* running. Keyed off live state rather than config: it may have been spawned
|
|
106
|
+
* at startup or out of band via `assistant schedules worker start`. Never
|
|
107
|
+
* throws.
|
|
108
|
+
*/
|
|
109
|
+
export function stopScheduleWorker(): void {
|
|
110
|
+
try {
|
|
111
|
+
const status = stopScheduleWorkerProcess();
|
|
112
|
+
if (status.status === "running") {
|
|
113
|
+
log.info({ pid: status.pid }, "Sent SIGTERM to schedule worker process");
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
log.warn({ err }, "Failed to stop schedule worker process (non-fatal)");
|
|
117
|
+
}
|
|
118
|
+
}
|