@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,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pure routing logic
|
|
2
|
+
* Pure routing logic for the voice call setup phase.
|
|
3
3
|
*
|
|
4
4
|
* Given a setup context (call session, actor trust, voice config, ACL policy),
|
|
5
|
-
* returns a discriminated union describing what the
|
|
5
|
+
* returns a discriminated union describing what the call session should do
|
|
6
6
|
* next — without performing any side effects itself.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { AdmissionPolicy, TrustVerdict } from "@vellumai/gateway-client";
|
|
10
10
|
|
|
11
11
|
import { getConfig } from "../config/loader.js";
|
|
12
|
-
import { getContact } from "../contacts/contact-store.js";
|
|
13
|
-
import { findActiveVoiceInvites } from "../persistence/invite-store.js";
|
|
14
12
|
import {
|
|
15
13
|
type ActorTrustContext,
|
|
16
14
|
resolveActorTrust,
|
|
@@ -26,6 +24,7 @@ import {
|
|
|
26
24
|
verdictMemberUnresolvable,
|
|
27
25
|
} from "../runtime/trust-verdict-consumer.js";
|
|
28
26
|
import { getLogger } from "../util/logger.js";
|
|
27
|
+
import { getActiveVoiceInvite } from "./gateway-invite-reader.js";
|
|
29
28
|
import type { CallSession } from "./types.js";
|
|
30
29
|
|
|
31
30
|
const log = getLogger("relay-setup-router");
|
|
@@ -54,7 +53,7 @@ interface SetupContext {
|
|
|
54
53
|
|
|
55
54
|
// ── Setup outcomes ───────────────────────────────────────────────────
|
|
56
55
|
|
|
57
|
-
type SetupOutcome =
|
|
56
|
+
export type SetupOutcome =
|
|
58
57
|
| { action: "normal_call"; isInbound: boolean }
|
|
59
58
|
| {
|
|
60
59
|
action: "verification";
|
|
@@ -76,9 +75,9 @@ type SetupOutcome =
|
|
|
76
75
|
assistantId: string;
|
|
77
76
|
fromNumber: string;
|
|
78
77
|
/**
|
|
79
|
-
* Display name of the invitee. For inbound redemptions,
|
|
80
|
-
*
|
|
81
|
-
*
|
|
78
|
+
* Display name of the invitee. For inbound redemptions, supplied by the
|
|
79
|
+
* gateway's active-voice-invite read (bound contact `displayName`
|
|
80
|
+
* preferred, invite `friendName` fallback). For outbound invite calls,
|
|
82
81
|
* carries the session-recorded `inviteFriendName`. When null/empty, the
|
|
83
82
|
* relay uses a neutral "Hi there" greeting instead of substituting the
|
|
84
83
|
* channel address.
|
|
@@ -107,17 +106,18 @@ export interface SetupResolved {
|
|
|
107
106
|
// ── Router ───────────────────────────────────────────────────────────
|
|
108
107
|
|
|
109
108
|
/**
|
|
110
|
-
* Determine the setup outcome for
|
|
109
|
+
* Determine the setup outcome for a starting call session.
|
|
111
110
|
*
|
|
112
|
-
* This function is pure routing logic — it reads state
|
|
113
|
-
*
|
|
114
|
-
* messages). The caller
|
|
115
|
-
* for acting on
|
|
111
|
+
* This function is pure routing logic — it reads state (including the
|
|
112
|
+
* gateway's active-voice-invite view) but performs no side effects (no
|
|
113
|
+
* call-session mutations, no event recording, no WS messages). The caller
|
|
114
|
+
* (the media-stream server's start handler) is responsible for acting on
|
|
115
|
+
* the returned outcome.
|
|
116
116
|
*/
|
|
117
|
-
export function routeSetup(ctx: SetupContext): {
|
|
117
|
+
export async function routeSetup(ctx: SetupContext): Promise<{
|
|
118
118
|
outcome: SetupOutcome;
|
|
119
119
|
resolved: SetupResolved;
|
|
120
|
-
} {
|
|
120
|
+
}> {
|
|
121
121
|
const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
|
|
122
122
|
const isInbound = ctx.session?.initiatedFromConversationId == null;
|
|
123
123
|
const otherPartyNumber = isInbound ? ctx.from : ctx.to;
|
|
@@ -302,44 +302,23 @@ export function routeSetup(ctx: SetupContext): {
|
|
|
302
302
|
};
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
// Check for active voice
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
});
|
|
311
|
-
} catch (err) {
|
|
312
|
-
log.warn(
|
|
313
|
-
{ err, callSessionId: ctx.callSessionId },
|
|
314
|
-
"Failed to check voice invites for unknown caller",
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const now = Date.now();
|
|
319
|
-
const nonExpiredInvites = voiceInvites.filter(
|
|
320
|
-
(i) => !i.expiresAt || i.expiresAt > now,
|
|
321
|
-
);
|
|
305
|
+
// Check for an active voice invite. The gateway row is the lifecycle
|
|
306
|
+
// authority; the reader fails soft to `null` on any gateway failure, so a
|
|
307
|
+
// gateway blip falls through to the unverified-caller flows below instead
|
|
308
|
+
// of stalling setup.
|
|
309
|
+
const voiceInvite = await getActiveVoiceInvite(ctx.from);
|
|
322
310
|
|
|
323
|
-
if (
|
|
324
|
-
const matchedInvite = nonExpiredInvites[0];
|
|
311
|
+
if (voiceInvite) {
|
|
325
312
|
log.info(
|
|
326
313
|
{ callSessionId: ctx.callSessionId, from: ctx.from },
|
|
327
314
|
"Inbound voice ACL: unknown caller has active voice invite — entering redemption flow",
|
|
328
315
|
);
|
|
329
|
-
// Resolve the invitee's name from the bound contact's displayName so
|
|
330
|
-
// the post-redemption greeting matches what the guardian sees in the
|
|
331
|
-
// contact graph. `contact_id` is NOT NULL on the invite row, so every
|
|
332
|
-
// invite is bound — when the contact has no displayName the greeting
|
|
333
|
-
// falls through to the neutral "Hi there" copy in relay-server.ts
|
|
334
|
-
// rather than a stale free-text `friend_name` label.
|
|
335
|
-
const boundContact = getContact(matchedInvite.contactId);
|
|
336
|
-
const inviteeName = boundContact?.displayName?.trim() || null;
|
|
337
316
|
return {
|
|
338
317
|
outcome: {
|
|
339
318
|
action: "invite_redemption",
|
|
340
319
|
assistantId,
|
|
341
320
|
fromNumber: ctx.from,
|
|
342
|
-
inviteeName: inviteeName
|
|
321
|
+
inviteeName: voiceInvite.inviteeName,
|
|
343
322
|
},
|
|
344
323
|
resolved,
|
|
345
324
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Verification logic for the voice call setup pipeline.
|
|
3
3
|
*
|
|
4
4
|
* These pure-ish functions encapsulate the decision-making for guardian code
|
|
5
|
-
* verification and invite code redemption without
|
|
6
|
-
*
|
|
7
|
-
* (
|
|
5
|
+
* verification and invite code redemption without mutating call-session
|
|
6
|
+
* state. They return structured result objects that the caller
|
|
7
|
+
* (CallSetupFlow) interprets to drive side-effects (TTS, session updates,
|
|
8
8
|
* timer scheduling, etc.).
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
getGuardianBinding,
|
|
13
13
|
validateAndConsumeVerification,
|
|
14
14
|
} from "../runtime/channel-verification-service.js";
|
|
15
|
-
import { redeemVoiceInviteCode } from "../runtime/invite-service.js";
|
|
16
15
|
import {
|
|
17
16
|
composeVerificationVoice,
|
|
18
17
|
GUARDIAN_VERIFY_TEMPLATE_KEYS,
|
|
19
18
|
} from "../runtime/verification-templates.js";
|
|
19
|
+
import { redeemVoiceInviteViaGateway } from "./gateway-invite-reader.js";
|
|
20
20
|
import type { CallEventType } from "./types.js";
|
|
21
21
|
|
|
22
22
|
// ── parseDigitsFromSpeech ──────────────────────────────────────────────
|
|
@@ -221,7 +221,6 @@ export async function attemptVerificationCode(
|
|
|
221
221
|
// ── Invite code redemption ─────────────────────────────────────────────
|
|
222
222
|
|
|
223
223
|
interface InviteRedemptionParams {
|
|
224
|
-
inviteRedemptionAssistantId: string;
|
|
225
224
|
inviteRedemptionFromNumber: string;
|
|
226
225
|
enteredCode: string;
|
|
227
226
|
/** Resolved guardian label used in the failure TTS message. */
|
|
@@ -233,7 +232,7 @@ type InviteRedemptionResult =
|
|
|
233
232
|
outcome: "success";
|
|
234
233
|
memberId: string;
|
|
235
234
|
type: "redeemed" | "already_member";
|
|
236
|
-
inviteId
|
|
235
|
+
inviteId: string;
|
|
237
236
|
}
|
|
238
237
|
| {
|
|
239
238
|
outcome: "failure";
|
|
@@ -241,33 +240,27 @@ type InviteRedemptionResult =
|
|
|
241
240
|
};
|
|
242
241
|
|
|
243
242
|
/**
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
243
|
+
* Redeem an entered invite code for the caller at the gateway — the single
|
|
244
|
+
* lifecycle authority for voice invites. Fails CLOSED: any gateway failure is
|
|
245
|
+
* the generic failure outcome with no local fallback. Returns a structured
|
|
246
|
+
* result so the caller can handle state mutations and session updates.
|
|
247
247
|
*/
|
|
248
248
|
export async function attemptInviteCodeRedemption(
|
|
249
249
|
params: InviteRedemptionParams,
|
|
250
250
|
): Promise<InviteRedemptionResult> {
|
|
251
|
-
const {
|
|
252
|
-
|
|
251
|
+
const { inviteRedemptionFromNumber, enteredCode, guardianLabel } = params;
|
|
252
|
+
|
|
253
|
+
const result = await redeemVoiceInviteViaGateway(
|
|
253
254
|
inviteRedemptionFromNumber,
|
|
254
255
|
enteredCode,
|
|
255
|
-
|
|
256
|
-
} = params;
|
|
257
|
-
|
|
258
|
-
const result = await redeemVoiceInviteCode({
|
|
259
|
-
assistantId: inviteRedemptionAssistantId,
|
|
260
|
-
callerExternalUserId: inviteRedemptionFromNumber,
|
|
261
|
-
sourceChannel: "phone",
|
|
262
|
-
code: enteredCode,
|
|
263
|
-
});
|
|
256
|
+
);
|
|
264
257
|
|
|
265
258
|
if (result.ok) {
|
|
266
259
|
return {
|
|
267
260
|
outcome: "success",
|
|
268
|
-
memberId: result.
|
|
269
|
-
type: result.
|
|
270
|
-
|
|
261
|
+
memberId: result.outcome.contactId,
|
|
262
|
+
type: result.outcome.result,
|
|
263
|
+
inviteId: result.outcome.inviteId,
|
|
271
264
|
};
|
|
272
265
|
}
|
|
273
266
|
|
|
@@ -8,10 +8,18 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { loadConfig } from "../config/loader.js";
|
|
11
|
+
import {
|
|
12
|
+
getCatalogProvider,
|
|
13
|
+
listCatalogProviderIds,
|
|
14
|
+
} from "../tts/provider-catalog.js";
|
|
11
15
|
import { getTtsProvider } from "../tts/provider-registry.js";
|
|
12
16
|
import { resolveTtsConfig } from "../tts/tts-config-resolver.js";
|
|
13
|
-
import type { TtsProvider } from "../tts/types.js";
|
|
17
|
+
import type { TtsProvider, TtsProviderId } from "../tts/types.js";
|
|
14
18
|
import { getLogger } from "../util/logger.js";
|
|
19
|
+
import {
|
|
20
|
+
evaluateTelephonyTtsPlayability,
|
|
21
|
+
fishAudioReferenceIdConfigured,
|
|
22
|
+
} from "./telephony-tts-capability.js";
|
|
15
23
|
import { resolveCallStrategy } from "./tts-call-strategy.js";
|
|
16
24
|
|
|
17
25
|
const log = getLogger("resolve-call-tts-provider");
|
|
@@ -27,8 +35,10 @@ export interface ResolvedCallTts {
|
|
|
27
35
|
/**
|
|
28
36
|
* True when the catalog's `callMode` is `"synthesized-play"` -- audio
|
|
29
37
|
* is synthesized via the provider API and streamed through the audio
|
|
30
|
-
* store. False when `callMode` is `"native-twilio"` -- text
|
|
31
|
-
*
|
|
38
|
+
* store. False when `callMode` is `"native-twilio"` -- text is sent
|
|
39
|
+
* via `sendTextToken()`, which the media-stream transport re-synthesizes
|
|
40
|
+
* through daemon TTS. (Collapsing the callMode split is a documented
|
|
41
|
+
* deferred follow-up.)
|
|
32
42
|
*/
|
|
33
43
|
useSynthesizedPath: boolean;
|
|
34
44
|
|
|
@@ -47,6 +57,11 @@ export interface ResolveCallTtsOptions {
|
|
|
47
57
|
* because its {@link audioBufferToFrames} can only correctly
|
|
48
58
|
* transcode WAV (PCM) to mu-law -- compressed formats (mp3, opus)
|
|
49
59
|
* are sent as raw bytes and produce garbled audio.
|
|
60
|
+
*
|
|
61
|
+
* Also gates the media-stream playability guard: a configured provider
|
|
62
|
+
* that cannot produce playable PCM/WAV audio (or lacks credentials) is
|
|
63
|
+
* swapped for a playable fallback provider instead of resolving into a
|
|
64
|
+
* provider whose only possible media-stream outcome is silence.
|
|
50
65
|
*/
|
|
51
66
|
preferWav?: boolean;
|
|
52
67
|
}
|
|
@@ -63,49 +78,75 @@ export interface ResolveCallTtsOptions {
|
|
|
63
78
|
* decision path used by `voice-quality.ts`. Providers with
|
|
64
79
|
* `callMode: "synthesized-play"` have their audio streamed through the
|
|
65
80
|
* audio store and played via `sendPlayUrl`. Providers with
|
|
66
|
-
* `callMode: "native-twilio"`
|
|
67
|
-
*
|
|
81
|
+
* `callMode: "native-twilio"` send text via `sendTextToken`, which the
|
|
82
|
+
* media-stream transport re-synthesizes through daemon TTS.
|
|
83
|
+
*
|
|
84
|
+
* For WAV-requiring transports (`preferWav`, i.e. media-stream), the
|
|
85
|
+
* resolved provider is validated against the media-stream playability
|
|
86
|
+
* capability (format + credentials); a not-playable provider is replaced
|
|
87
|
+
* by {@link findPlayableTelephonyTtsFallback}.
|
|
68
88
|
*
|
|
69
89
|
* Falls back to the native path with `mp3` format when the config is
|
|
70
90
|
* missing a `services.tts` block or the provider is not registered
|
|
71
91
|
* (e.g. unit tests or early startup).
|
|
72
92
|
*/
|
|
73
|
-
export function resolveCallTtsProvider(
|
|
93
|
+
export async function resolveCallTtsProvider(
|
|
74
94
|
options?: ResolveCallTtsOptions,
|
|
75
|
-
): ResolvedCallTts {
|
|
95
|
+
): Promise<ResolvedCallTts> {
|
|
76
96
|
try {
|
|
77
97
|
const config = loadConfig();
|
|
78
98
|
const resolved = resolveTtsConfig(config);
|
|
79
|
-
const provider = getTtsProvider(resolved.provider);
|
|
80
99
|
|
|
81
100
|
// Use the catalog's callMode to decide the call path -- the same
|
|
82
101
|
// decision path used by voice-quality.ts via resolveCallStrategy().
|
|
83
102
|
const strategy = resolveCallStrategy(config);
|
|
84
|
-
const useSynthesizedPath = strategy.callMode === "synthesized-play";
|
|
85
103
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
let providerId = resolved.provider;
|
|
105
|
+
let useSynthesizedPath = strategy.callMode === "synthesized-play";
|
|
106
|
+
|
|
107
|
+
// Preflight provider-specific config invariants that would otherwise
|
|
108
|
+
// fail only at first synthesis call. Fish Audio requires a reference
|
|
109
|
+
// ID when no per-request voiceId is supplied (the telephony default).
|
|
110
|
+
const fishAudioUnusable =
|
|
111
|
+
providerId === "fish-audio" && !fishAudioReferenceIdConfigured();
|
|
112
|
+
|
|
113
|
+
if (options?.preferWav) {
|
|
114
|
+
// Media-stream transport: every spoken turn is synthesized, so the
|
|
115
|
+
// provider must produce playable PCM/WAV with resolvable credentials
|
|
116
|
+
// and satisfied config invariants (the capability check covers the
|
|
117
|
+
// fish-audio referenceId rule). Swap in a playable fallback rather
|
|
118
|
+
// than resolving into a provider that can only be silent.
|
|
119
|
+
const capability = await evaluateTelephonyTtsPlayability(providerId);
|
|
120
|
+
if (capability.status === "not-playable") {
|
|
121
|
+
const reason = capability.reason;
|
|
122
|
+
const fallbackId = await findPlayableTelephonyTtsFallback(providerId);
|
|
123
|
+
if (fallbackId) {
|
|
124
|
+
log.warn(
|
|
125
|
+
{ providerId, reason, fallbackProviderId: fallbackId },
|
|
126
|
+
"Configured TTS provider is not playable on the media-stream transport; falling back",
|
|
127
|
+
);
|
|
128
|
+
providerId = fallbackId;
|
|
129
|
+
useSynthesizedPath =
|
|
130
|
+
getCatalogProvider(fallbackId).callMode === "synthesized-play";
|
|
131
|
+
} else {
|
|
132
|
+
log.warn(
|
|
133
|
+
{ providerId, reason },
|
|
134
|
+
"Configured TTS provider is not playable on the media-stream transport and no playable fallback provider is available",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
106
137
|
}
|
|
138
|
+
} else if (useSynthesizedPath && fishAudioUnusable) {
|
|
139
|
+
// Non-WAV transport: degrade to the native token path rather than
|
|
140
|
+
// letting the call stay silent.
|
|
141
|
+
log.warn(
|
|
142
|
+
{ provider: providerId },
|
|
143
|
+
"Synthesized call TTS disabled: fish-audio.referenceId is not configured; falling back to native token path",
|
|
144
|
+
);
|
|
145
|
+
return { provider: null, useSynthesizedPath: false, audioFormat: "mp3" };
|
|
107
146
|
}
|
|
108
147
|
|
|
148
|
+
const provider = getTtsProvider(providerId);
|
|
149
|
+
|
|
109
150
|
// Read the user-configured audio format from the resolved provider
|
|
110
151
|
// config so the streaming store entry's content-type matches the
|
|
111
152
|
// actual audio bytes the provider produces.
|
|
@@ -134,3 +175,29 @@ export function resolveCallTtsProvider(
|
|
|
134
175
|
return { provider: null, useSynthesizedPath: false, audioFormat: "mp3" };
|
|
135
176
|
}
|
|
136
177
|
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Find a catalog provider that can produce playable media-stream audio
|
|
181
|
+
* with resolvable credentials.
|
|
182
|
+
*
|
|
183
|
+
* Preference order: the ElevenLabs default first (when its key resolves),
|
|
184
|
+
* then the remaining catalog providers in display order. The playability
|
|
185
|
+
* capability already applies the fish-audio `referenceId` invariant, so a
|
|
186
|
+
* referenceId-less fish-audio setup is never selected. Returns `null` when
|
|
187
|
+
* no provider qualifies.
|
|
188
|
+
*/
|
|
189
|
+
export async function findPlayableTelephonyTtsFallback(
|
|
190
|
+
excludeProviderId?: TtsProviderId,
|
|
191
|
+
): Promise<TtsProviderId | null> {
|
|
192
|
+
const candidates = [
|
|
193
|
+
...new Set<TtsProviderId>(["elevenlabs", ...listCatalogProviderIds()]),
|
|
194
|
+
].filter((id) => id !== excludeProviderId);
|
|
195
|
+
|
|
196
|
+
for (const candidateId of candidates) {
|
|
197
|
+
const capability = await evaluateTelephonyTtsPlayability(candidateId);
|
|
198
|
+
if (capability.status === "playable") {
|
|
199
|
+
return candidateId;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
package/src/calls/stt-hints.ts
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
getGuardianDelivery,
|
|
4
|
-
voiceGuardianDisplayName,
|
|
5
|
-
} from "../contacts/guardian-delivery-reader.js";
|
|
6
|
-
import { getAssistantName } from "../daemon/identity-helpers.js";
|
|
7
|
-
import { DEFAULT_USER_REFERENCE, resolveGuardianName } from "../prompts/user-reference.js";
|
|
8
|
-
import { getLogger } from "../util/logger.js";
|
|
9
|
-
|
|
10
|
-
const logger = getLogger("stt-hints");
|
|
1
|
+
import { DEFAULT_USER_REFERENCE } from "../prompts/user-reference.js";
|
|
11
2
|
|
|
12
3
|
export interface SttHintsInput {
|
|
13
4
|
staticHints: string[];
|
|
@@ -28,6 +19,9 @@ const MAX_HINTS_LENGTH = 500;
|
|
|
28
19
|
* comma-separated string suitable for speech-to-text provider hint APIs.
|
|
29
20
|
*
|
|
30
21
|
* Pure function — no DB or filesystem dependencies.
|
|
22
|
+
*
|
|
23
|
+
* Dormant: the `calls.voice.hints` config key supplies static hints, but
|
|
24
|
+
* no daemon transcriber consumes the assembled string yet.
|
|
31
25
|
*/
|
|
32
26
|
export function buildSttHints(input: SttHintsInput): string {
|
|
33
27
|
const hints: string[] = [...input.staticHints];
|
|
@@ -44,26 +38,41 @@ export function buildSttHints(input: SttHintsInput): string {
|
|
|
44
38
|
hints.push(input.guardianName.trim());
|
|
45
39
|
}
|
|
46
40
|
|
|
47
|
-
if (
|
|
41
|
+
if (
|
|
42
|
+
input.inviteFriendName != null &&
|
|
43
|
+
input.inviteFriendName.trim().length > 0
|
|
44
|
+
) {
|
|
48
45
|
hints.push(input.inviteFriendName.trim());
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
if (
|
|
48
|
+
if (
|
|
49
|
+
input.inviteGuardianName != null &&
|
|
50
|
+
input.inviteGuardianName.trim().length > 0
|
|
51
|
+
) {
|
|
52
52
|
hints.push(input.inviteGuardianName.trim());
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
if (
|
|
55
|
+
if (
|
|
56
|
+
input.targetContactName != null &&
|
|
57
|
+
input.targetContactName.trim().length > 0
|
|
58
|
+
) {
|
|
56
59
|
hints.push(input.targetContactName.trim());
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
if (
|
|
62
|
+
if (
|
|
63
|
+
input.callerContactName != null &&
|
|
64
|
+
input.callerContactName.trim().length > 0
|
|
65
|
+
) {
|
|
60
66
|
hints.push(input.callerContactName.trim());
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
// Extract potential proper nouns from task description.
|
|
64
70
|
// Split on sentence boundaries, then for each sentence take words
|
|
65
71
|
// after the first that start with an uppercase letter.
|
|
66
|
-
if (
|
|
72
|
+
if (
|
|
73
|
+
input.taskDescription != null &&
|
|
74
|
+
input.taskDescription.trim().length > 0
|
|
75
|
+
) {
|
|
67
76
|
// Split on sentence-ending punctuation followed by whitespace, but avoid
|
|
68
77
|
// splitting on periods after common abbreviations (Dr., Mr., etc.) so that
|
|
69
78
|
// names like "Dr. Smith" aren't fragmented and dropped by the first-word skip.
|
|
@@ -112,75 +121,3 @@ export function buildSttHints(input: SttHintsInput): string {
|
|
|
112
121
|
}
|
|
113
122
|
return truncated.slice(0, lastComma);
|
|
114
123
|
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Wire real data sources (contacts DB, identity helpers, config) into
|
|
118
|
-
* {@link buildSttHints}. All DB lookups are best-effort — errors are
|
|
119
|
-
* logged but never propagate so hints can never fail a call.
|
|
120
|
-
*/
|
|
121
|
-
export async function resolveCallHints(
|
|
122
|
-
session: {
|
|
123
|
-
task: string | null;
|
|
124
|
-
toNumber: string;
|
|
125
|
-
fromNumber: string;
|
|
126
|
-
direction: "inbound" | "outbound";
|
|
127
|
-
inviteFriendName: string | null;
|
|
128
|
-
inviteGuardianName: string | null;
|
|
129
|
-
} | null,
|
|
130
|
-
staticHints: string[],
|
|
131
|
-
): Promise<string> {
|
|
132
|
-
const assistantName = getAssistantName();
|
|
133
|
-
|
|
134
|
-
// Resolve the guardian displayName from the gateway binding for STT vocabulary.
|
|
135
|
-
let guardianDisplayName: string | undefined;
|
|
136
|
-
try {
|
|
137
|
-
const list = await getGuardianDelivery();
|
|
138
|
-
guardianDisplayName = voiceGuardianDisplayName(list);
|
|
139
|
-
} catch (err) {
|
|
140
|
-
logger.warn({ err }, "Failed to look up guardian contact for STT hints");
|
|
141
|
-
}
|
|
142
|
-
const guardianName = resolveGuardianName(guardianDisplayName);
|
|
143
|
-
|
|
144
|
-
let targetContactName: string | null = null;
|
|
145
|
-
let callerContactName: string | null = null;
|
|
146
|
-
let recentContactNames: string[] = [];
|
|
147
|
-
|
|
148
|
-
// For inbound calls, fromNumber is the caller (the interesting party);
|
|
149
|
-
// toNumber is the assistant's own Twilio number (not useful for contact lookup).
|
|
150
|
-
// For outbound calls, toNumber is who we're calling.
|
|
151
|
-
try {
|
|
152
|
-
if (session) {
|
|
153
|
-
const otherPartyNumber =
|
|
154
|
-
session.direction === "inbound" ? session.fromNumber : session.toNumber;
|
|
155
|
-
const otherPartyContact = findContactByAddress("phone", otherPartyNumber);
|
|
156
|
-
if (otherPartyContact) {
|
|
157
|
-
if (session.direction === "inbound") {
|
|
158
|
-
callerContactName = otherPartyContact.displayName;
|
|
159
|
-
} else {
|
|
160
|
-
targetContactName = otherPartyContact.displayName;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
} catch (err) {
|
|
165
|
-
logger.warn({ err }, "Failed to look up contact for STT hints");
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
const recentContacts = listContacts(15);
|
|
170
|
-
recentContactNames = recentContacts.map((c) => c.displayName);
|
|
171
|
-
} catch (err) {
|
|
172
|
-
logger.warn({ err }, "Failed to list recent contacts for STT hints");
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return buildSttHints({
|
|
176
|
-
staticHints,
|
|
177
|
-
assistantName,
|
|
178
|
-
guardianName,
|
|
179
|
-
taskDescription: session?.task ?? null,
|
|
180
|
-
targetContactName,
|
|
181
|
-
callerContactName,
|
|
182
|
-
inviteFriendName: session?.inviteFriendName ?? null,
|
|
183
|
-
inviteGuardianName: session?.inviteGuardianName ?? null,
|
|
184
|
-
recentContactNames,
|
|
185
|
-
});
|
|
186
|
-
}
|