@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
|
@@ -43,7 +43,10 @@ import {
|
|
|
43
43
|
} from "../notifications/guardian-question-mode.js";
|
|
44
44
|
import { getLogger } from "../util/logger.js";
|
|
45
45
|
import { runApprovalConversationTurn } from "./approval-conversation-turn.js";
|
|
46
|
-
import
|
|
46
|
+
import {
|
|
47
|
+
type ApprovalAction,
|
|
48
|
+
isApprovalAction,
|
|
49
|
+
} from "./channel-approval-types.js";
|
|
47
50
|
import type {
|
|
48
51
|
ApprovalConversationContext,
|
|
49
52
|
ApprovalConversationGenerator,
|
|
@@ -143,8 +146,6 @@ export interface GuardianReplyResult {
|
|
|
143
146
|
// Callback data parser — format: "apr:<requestId>:<action>"
|
|
144
147
|
// ---------------------------------------------------------------------------
|
|
145
148
|
|
|
146
|
-
const VALID_ACTIONS: ReadonlySet<string> = new Set(["approve_once", "reject"]);
|
|
147
|
-
|
|
148
149
|
const LEGACY_CALLBACK_MAP: Record<string, string> = {
|
|
149
150
|
approve_10m: "approve_once",
|
|
150
151
|
approve_conversation: "approve_once",
|
|
@@ -158,12 +159,16 @@ interface ParsedCallback {
|
|
|
158
159
|
|
|
159
160
|
function parseCallbackAction(data: string): ParsedCallback | null {
|
|
160
161
|
const parts = data.split(":");
|
|
161
|
-
if (parts.length < 3 || parts[0] !== "apr")
|
|
162
|
+
if (parts.length < 3 || parts[0] !== "apr") {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
162
165
|
const requestId = parts[1];
|
|
163
166
|
const rawAction = parts.slice(2).join(":");
|
|
164
167
|
const action = LEGACY_CALLBACK_MAP[rawAction] ?? rawAction;
|
|
165
|
-
if (!requestId || !
|
|
166
|
-
|
|
168
|
+
if (!requestId || !isApprovalAction(action)) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return { requestId, action };
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
// ---------------------------------------------------------------------------
|
|
@@ -198,11 +203,15 @@ function parseRequestCode(
|
|
|
198
203
|
// Request codes are 6 hex chars (A-F, 0-9), uppercase
|
|
199
204
|
const upper = cleaned.toUpperCase();
|
|
200
205
|
const match = upper.match(/^([A-F0-9]{6})(?:\s|$)/);
|
|
201
|
-
if (!match)
|
|
206
|
+
if (!match) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
202
209
|
|
|
203
210
|
const code = match[1];
|
|
204
211
|
const request = getCanonicalGuardianRequestByCode(code);
|
|
205
|
-
if (!request)
|
|
212
|
+
if (!request) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
206
215
|
|
|
207
216
|
// Scope to the current conversation when requested, so a code belonging
|
|
208
217
|
// to a different conversation is not consumed here. Requests with
|
|
@@ -501,9 +510,12 @@ export async function routeGuardianReply(
|
|
|
501
510
|
};
|
|
502
511
|
}
|
|
503
512
|
|
|
504
|
-
// Remaining text present — infer the decision action from it
|
|
505
|
-
//
|
|
506
|
-
const action = inferActionFromText(
|
|
513
|
+
// Remaining text present — infer the decision action from it, using
|
|
514
|
+
// the introduction-card verb set for access requests.
|
|
515
|
+
const action = inferActionFromText(
|
|
516
|
+
codeResult.remainingText,
|
|
517
|
+
request.kind,
|
|
518
|
+
);
|
|
507
519
|
|
|
508
520
|
return applyDecision(
|
|
509
521
|
request.id,
|
|
@@ -553,7 +565,12 @@ export async function routeGuardianReply(
|
|
|
553
565
|
// approve/reject phrase ("approve", "yes", "reject", "no"), apply the
|
|
554
566
|
// decision directly instead of falling through to legacy handlers.
|
|
555
567
|
if (messageText.length > 0 && pendingRequests.length > 0) {
|
|
556
|
-
|
|
568
|
+
// The action is only applied when exactly one request is pending, so the
|
|
569
|
+
// kind-aware verb set is used for that single known target.
|
|
570
|
+
const inferredAction = inferDecisionActionFromFreeText(
|
|
571
|
+
messageText,
|
|
572
|
+
pendingRequests.length === 1 ? pendingRequests[0].kind : undefined,
|
|
573
|
+
);
|
|
557
574
|
if (inferredAction) {
|
|
558
575
|
if (pendingRequests.length === 1) {
|
|
559
576
|
return applyDecision(
|
|
@@ -640,8 +657,13 @@ export async function routeGuardianReply(
|
|
|
640
657
|
};
|
|
641
658
|
}
|
|
642
659
|
|
|
643
|
-
// Decision-bearing disposition from the engine
|
|
644
|
-
|
|
660
|
+
// Decision-bearing disposition from the engine. The engine's allowed
|
|
661
|
+
// actions are a subset of ApprovalAction; an out-of-vocabulary
|
|
662
|
+
// disposition is not consumed as a decision.
|
|
663
|
+
if (!isApprovalAction(engineResult.disposition)) {
|
|
664
|
+
return notConsumed();
|
|
665
|
+
}
|
|
666
|
+
const decisionAction = engineResult.disposition;
|
|
645
667
|
|
|
646
668
|
// Resolve the target request
|
|
647
669
|
const targetId =
|
|
@@ -839,28 +861,107 @@ function normalizeDecisionPhrase(text: string): string {
|
|
|
839
861
|
.replace(/\s+/g, " ");
|
|
840
862
|
}
|
|
841
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Introduction-card phrases recognized without a request code. Checked before
|
|
866
|
+
* the generic reject vocabulary so a bare "block" on an access request maps
|
|
867
|
+
* to the block action (revoke) rather than the weaker leave-unverified
|
|
868
|
+
* outcome.
|
|
869
|
+
*/
|
|
870
|
+
const EXPLICIT_INTRODUCTION_PHRASES: ReadonlyMap<string, ApprovalAction> =
|
|
871
|
+
new Map([
|
|
872
|
+
["trust", "trust"],
|
|
873
|
+
["trust them", "trust"],
|
|
874
|
+
["verify", "verify_code"],
|
|
875
|
+
["verify them", "verify_code"],
|
|
876
|
+
["block", "block"],
|
|
877
|
+
["block them", "block"],
|
|
878
|
+
["ban", "block"],
|
|
879
|
+
["ban them", "block"],
|
|
880
|
+
]);
|
|
881
|
+
|
|
842
882
|
/**
|
|
843
883
|
* Strict free-text decision parser used when no request code is present.
|
|
844
|
-
* Returns null unless the message starts with an explicit
|
|
884
|
+
* Returns null unless the message starts with an explicit decision cue.
|
|
885
|
+
*
|
|
886
|
+
* For `access_request` targets the introduction-card verbs are recognized
|
|
887
|
+
* first, and the generic rejection vocabulary maps to `leave_unverified`
|
|
888
|
+
*.
|
|
889
|
+
*
|
|
890
|
+
* Exported for tests.
|
|
845
891
|
*/
|
|
846
|
-
function inferDecisionActionFromFreeText(
|
|
892
|
+
export function inferDecisionActionFromFreeText(
|
|
893
|
+
text: string,
|
|
894
|
+
requestKind?: string,
|
|
895
|
+
): ApprovalAction | null {
|
|
847
896
|
const normalized = normalizeDecisionPhrase(text);
|
|
848
|
-
if (!normalized)
|
|
849
|
-
|
|
850
|
-
|
|
897
|
+
if (!normalized) {
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
if (requestKind === "access_request") {
|
|
901
|
+
const introductionAction = EXPLICIT_INTRODUCTION_PHRASES.get(normalized);
|
|
902
|
+
if (introductionAction) {
|
|
903
|
+
return introductionAction;
|
|
904
|
+
}
|
|
905
|
+
if (EXPLICIT_REJECT_PHRASES.has(normalized)) {
|
|
906
|
+
return "leave_unverified";
|
|
907
|
+
}
|
|
908
|
+
if (EXPLICIT_APPROVE_PHRASES.has(normalized)) {
|
|
909
|
+
return "approve_once";
|
|
910
|
+
}
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
if (EXPLICIT_REJECT_PHRASES.has(normalized)) {
|
|
914
|
+
return "reject";
|
|
915
|
+
}
|
|
916
|
+
if (EXPLICIT_APPROVE_PHRASES.has(normalized)) {
|
|
917
|
+
return "approve_once";
|
|
918
|
+
}
|
|
851
919
|
return null;
|
|
852
920
|
}
|
|
853
921
|
|
|
922
|
+
/**
|
|
923
|
+
* Introduction-card verbs for `access_request` requests. `trust` / `verify` /
|
|
924
|
+
* `block` map to their card actions; the generic reject vocabulary maps to
|
|
925
|
+
* leave-unverified (deny without revoking).
|
|
926
|
+
*/
|
|
927
|
+
const CODE_TRUST_PATTERNS = /^(trust|trusted)\b/i;
|
|
928
|
+
const CODE_VERIFY_PATTERNS = /^(verify|verification|code|handshake)\b/i;
|
|
929
|
+
const CODE_BLOCK_PATTERNS = /^(block|ban)\b/i;
|
|
930
|
+
|
|
854
931
|
/**
|
|
855
932
|
* Infer a guardian decision action from free-text after a request code.
|
|
856
933
|
* Defaults to approve_once unless clear rejection language is detected.
|
|
934
|
+
*
|
|
935
|
+
* For `access_request` requests, the introduction-card verbs (trust / verify
|
|
936
|
+
* / block) are recognized first, and rejection vocabulary maps to
|
|
937
|
+
* `leave_unverified`.
|
|
857
938
|
*/
|
|
858
|
-
function inferActionFromText(
|
|
939
|
+
function inferActionFromText(
|
|
940
|
+
text: string,
|
|
941
|
+
requestKind?: string,
|
|
942
|
+
): ApprovalAction {
|
|
859
943
|
if (!text || text.trim().length === 0) {
|
|
860
944
|
return "approve_once";
|
|
861
945
|
}
|
|
946
|
+
const trimmed = text.trim();
|
|
947
|
+
|
|
948
|
+
if (requestKind === "access_request") {
|
|
949
|
+
if (CODE_BLOCK_PATTERNS.test(trimmed)) {
|
|
950
|
+
return "block";
|
|
951
|
+
}
|
|
952
|
+
if (CODE_TRUST_PATTERNS.test(trimmed)) {
|
|
953
|
+
return "trust";
|
|
954
|
+
}
|
|
955
|
+
if (CODE_VERIFY_PATTERNS.test(trimmed)) {
|
|
956
|
+
return "verify_code";
|
|
957
|
+
}
|
|
958
|
+
if (CODE_REJECT_PATTERNS.test(trimmed)) {
|
|
959
|
+
return "leave_unverified";
|
|
960
|
+
}
|
|
961
|
+
return "approve_once";
|
|
962
|
+
}
|
|
862
963
|
|
|
863
|
-
if (CODE_REJECT_PATTERNS.test(
|
|
964
|
+
if (CODE_REJECT_PATTERNS.test(trimmed)) {
|
|
864
965
|
return "reject";
|
|
865
966
|
}
|
|
866
967
|
|
|
@@ -11,13 +11,7 @@ import {
|
|
|
11
11
|
activeMediaStreamSessions,
|
|
12
12
|
MediaStreamCallSession,
|
|
13
13
|
} from "../calls/media-stream-server.js";
|
|
14
|
-
import type { RelayWebSocketData } from "../calls/relay-server.js";
|
|
15
14
|
import {
|
|
16
|
-
activeRelayConnections,
|
|
17
|
-
RelayConnection,
|
|
18
|
-
} from "../calls/relay-server.js";
|
|
19
|
-
import {
|
|
20
|
-
handleConnectAction,
|
|
21
15
|
handleStatusCallback,
|
|
22
16
|
handleVoiceWebhook,
|
|
23
17
|
} from "../calls/twilio-routes.js";
|
|
@@ -61,6 +55,7 @@ import { withErrorHandling } from "./middleware/error-handler.js";
|
|
|
61
55
|
import {
|
|
62
56
|
extractClientIp,
|
|
63
57
|
ipRateLimiter,
|
|
58
|
+
isRateLimitExemptEndpoint,
|
|
64
59
|
rateLimitHeaders,
|
|
65
60
|
rateLimitResponse,
|
|
66
61
|
selectAuthenticatedRateLimiter,
|
|
@@ -104,7 +99,7 @@ const MAX_REQUEST_BODY_BYTES = 512 * 1024 * 1024;
|
|
|
104
99
|
/**
|
|
105
100
|
* WebSocket data attached to `/v1/calls/media-stream` connections.
|
|
106
101
|
* The `wsType` discriminator routes frames to the media-stream call
|
|
107
|
-
* session instead of the
|
|
102
|
+
* session instead of the other WebSocket handlers.
|
|
108
103
|
*/
|
|
109
104
|
interface MediaStreamWebSocketData {
|
|
110
105
|
wsType: "media-stream";
|
|
@@ -174,7 +169,6 @@ export class RuntimeHttpServer {
|
|
|
174
169
|
|
|
175
170
|
async start(): Promise<void> {
|
|
176
171
|
type AllWebSocketData =
|
|
177
|
-
| RelayWebSocketData
|
|
178
172
|
| MediaStreamWebSocketData
|
|
179
173
|
| SttStreamWebSocketData
|
|
180
174
|
| LiveVoiceWebSocketData;
|
|
@@ -187,8 +181,8 @@ export class RuntimeHttpServer {
|
|
|
187
181
|
websocket: {
|
|
188
182
|
open: (ws) => {
|
|
189
183
|
const data = ws.data as AllWebSocketData;
|
|
190
|
-
if (
|
|
191
|
-
const msData = data
|
|
184
|
+
if (data.wsType === "media-stream") {
|
|
185
|
+
const msData = data;
|
|
192
186
|
log.info(
|
|
193
187
|
{ callSessionId: msData.callSessionId },
|
|
194
188
|
"Media-stream WebSocket opened",
|
|
@@ -204,8 +198,8 @@ export class RuntimeHttpServer {
|
|
|
204
198
|
msData.session = session;
|
|
205
199
|
return;
|
|
206
200
|
}
|
|
207
|
-
if (
|
|
208
|
-
const sttData = data
|
|
201
|
+
if (data.wsType === "stt-stream") {
|
|
202
|
+
const sttData = data;
|
|
209
203
|
|
|
210
204
|
// The runtime is config-authoritative: always resolve the
|
|
211
205
|
// provider from `services.stt.provider` regardless of what
|
|
@@ -275,34 +269,25 @@ export class RuntimeHttpServer {
|
|
|
275
269
|
);
|
|
276
270
|
return;
|
|
277
271
|
}
|
|
278
|
-
if (
|
|
272
|
+
if (data.wsType === "live-voice") {
|
|
279
273
|
log.info("Live voice WebSocket opened");
|
|
280
274
|
return;
|
|
281
275
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (callSessionId) {
|
|
285
|
-
const connection = new RelayConnection(
|
|
286
|
-
ws as ServerWebSocket<RelayWebSocketData>,
|
|
287
|
-
callSessionId,
|
|
288
|
-
);
|
|
289
|
-
activeRelayConnections.set(callSessionId, connection);
|
|
290
|
-
}
|
|
276
|
+
log.warn("WebSocket opened with unknown data type — closing");
|
|
277
|
+
ws.close(1008, "Unknown WebSocket type");
|
|
291
278
|
},
|
|
292
279
|
message: (ws, message) => {
|
|
293
280
|
const data = ws.data as AllWebSocketData;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
msData.session?.handleMessage(raw);
|
|
281
|
+
if (data.wsType === "media-stream") {
|
|
282
|
+
const raw =
|
|
283
|
+
typeof message === "string"
|
|
284
|
+
? message
|
|
285
|
+
: new TextDecoder().decode(message);
|
|
286
|
+
data.session?.handleMessage(raw);
|
|
301
287
|
return;
|
|
302
288
|
}
|
|
303
|
-
if (
|
|
304
|
-
const
|
|
305
|
-
const session = sttData.session;
|
|
289
|
+
if (data.wsType === "stt-stream") {
|
|
290
|
+
const session = data.session;
|
|
306
291
|
if (!session) return;
|
|
307
292
|
|
|
308
293
|
if (typeof message === "string") {
|
|
@@ -317,7 +302,7 @@ export class RuntimeHttpServer {
|
|
|
317
302
|
}
|
|
318
303
|
return;
|
|
319
304
|
}
|
|
320
|
-
if (
|
|
305
|
+
if (data.wsType === "live-voice") {
|
|
321
306
|
void this.handleLiveVoiceMessage(
|
|
322
307
|
ws as ServerWebSocket<LiveVoiceWebSocketData>,
|
|
323
308
|
message,
|
|
@@ -336,16 +321,13 @@ export class RuntimeHttpServer {
|
|
|
336
321
|
});
|
|
337
322
|
return;
|
|
338
323
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const connection = activeRelayConnections.get(callSessionId);
|
|
342
|
-
connection?.handleMessage(raw);
|
|
343
|
-
}
|
|
324
|
+
log.warn("WebSocket message on unknown data type — closing");
|
|
325
|
+
ws.close(1008, "Unknown WebSocket type");
|
|
344
326
|
},
|
|
345
327
|
close: (ws, code, reason) => {
|
|
346
328
|
const data = ws.data as AllWebSocketData;
|
|
347
|
-
if (
|
|
348
|
-
const msData = data
|
|
329
|
+
if (data.wsType === "media-stream") {
|
|
330
|
+
const msData = data;
|
|
349
331
|
log.info(
|
|
350
332
|
{
|
|
351
333
|
callSessionId: msData.callSessionId,
|
|
@@ -372,8 +354,8 @@ export class RuntimeHttpServer {
|
|
|
372
354
|
}
|
|
373
355
|
return;
|
|
374
356
|
}
|
|
375
|
-
if (
|
|
376
|
-
const sttData = data
|
|
357
|
+
if (data.wsType === "stt-stream") {
|
|
358
|
+
const sttData = data;
|
|
377
359
|
log.info(
|
|
378
360
|
{
|
|
379
361
|
provider: sttData.provider,
|
|
@@ -394,7 +376,7 @@ export class RuntimeHttpServer {
|
|
|
394
376
|
}
|
|
395
377
|
return;
|
|
396
378
|
}
|
|
397
|
-
if (
|
|
379
|
+
if (data.wsType === "live-voice") {
|
|
398
380
|
log.info(
|
|
399
381
|
{
|
|
400
382
|
sessionId: data.sessionId,
|
|
@@ -406,17 +388,10 @@ export class RuntimeHttpServer {
|
|
|
406
388
|
this.releaseLiveVoiceSession(data, "websocket_close");
|
|
407
389
|
return;
|
|
408
390
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
"ConversationRelay WebSocket closed",
|
|
391
|
+
log.warn(
|
|
392
|
+
{ code, reason: reason?.toString() },
|
|
393
|
+
"WebSocket with unknown data type closed",
|
|
413
394
|
);
|
|
414
|
-
if (callSessionId) {
|
|
415
|
-
const connection = activeRelayConnections.get(callSessionId);
|
|
416
|
-
connection?.handleTransportClosed(code, reason?.toString());
|
|
417
|
-
connection?.destroy();
|
|
418
|
-
activeRelayConnections.delete(callSessionId);
|
|
419
|
-
}
|
|
420
395
|
},
|
|
421
396
|
},
|
|
422
397
|
});
|
|
@@ -551,17 +526,9 @@ export class RuntimeHttpServer {
|
|
|
551
526
|
return handleReadyz();
|
|
552
527
|
}
|
|
553
528
|
|
|
554
|
-
// WebSocket upgrade for
|
|
555
|
-
// Twilio WebSocket connections don't use bearer tokens
|
|
556
|
-
|
|
557
|
-
path.startsWith("/v1/calls/relay") &&
|
|
558
|
-
req.headers.get("upgrade")?.toLowerCase() === "websocket"
|
|
559
|
-
) {
|
|
560
|
-
return this.handleRelayUpgrade(req, server);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// WebSocket upgrade for Twilio Media Streams — same private-network
|
|
564
|
-
// restrictions as relay upgrades.
|
|
529
|
+
// WebSocket upgrade for Twilio Media Streams — before auth check because
|
|
530
|
+
// Twilio WebSocket connections don't use bearer tokens; restricted to
|
|
531
|
+
// private-network peers with a gateway service token.
|
|
565
532
|
if (
|
|
566
533
|
path.startsWith("/v1/calls/media-stream") &&
|
|
567
534
|
req.headers.get("upgrade")?.toLowerCase() === "websocket"
|
|
@@ -686,8 +653,13 @@ export class RuntimeHttpServer {
|
|
|
686
653
|
? selectAuthenticatedRateLimiter(clientIp)
|
|
687
654
|
: ipRateLimiter;
|
|
688
655
|
const limiterKind = token ? "authenticated" : "unauthenticated";
|
|
689
|
-
|
|
690
|
-
|
|
656
|
+
// Streaming (SSE) and liveness endpoints bypass the per-minute request
|
|
657
|
+
// limiter — see isRateLimitExemptEndpoint. `result` stays null for them,
|
|
658
|
+
// so no 429 is returned and no rate-limit headers are attached.
|
|
659
|
+
const result = isRateLimitExemptEndpoint(endpoint)
|
|
660
|
+
? null
|
|
661
|
+
: limiter.check(clientIp, path);
|
|
662
|
+
if (result && !result.allowed) {
|
|
691
663
|
return rateLimitResponse(result, {
|
|
692
664
|
clientIp,
|
|
693
665
|
deniedPath: path,
|
|
@@ -705,8 +677,10 @@ export class RuntimeHttpServer {
|
|
|
705
677
|
const response =
|
|
706
678
|
routerResponse ?? httpError("NOT_FOUND", "Not found", 404);
|
|
707
679
|
const headers = new Headers(response.headers);
|
|
708
|
-
|
|
709
|
-
|
|
680
|
+
if (result) {
|
|
681
|
+
for (const [k, v] of Object.entries(rateLimitHeaders(result))) {
|
|
682
|
+
headers.set(k, v);
|
|
683
|
+
}
|
|
710
684
|
}
|
|
711
685
|
return new Response(response.body, {
|
|
712
686
|
status: response.status,
|
|
@@ -747,35 +721,6 @@ export class RuntimeHttpServer {
|
|
|
747
721
|
return null;
|
|
748
722
|
}
|
|
749
723
|
|
|
750
|
-
private handleRelayUpgrade(
|
|
751
|
-
req: Request,
|
|
752
|
-
server: ReturnType<typeof Bun.serve>,
|
|
753
|
-
): Response {
|
|
754
|
-
if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
|
|
755
|
-
return httpError(
|
|
756
|
-
"FORBIDDEN",
|
|
757
|
-
"Direct relay access disabled — only private network peers allowed",
|
|
758
|
-
403,
|
|
759
|
-
);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
// Verify the gateway service token before accepting the upgrade.
|
|
763
|
-
const tokenError = this.verifyGatewayServiceToken(req);
|
|
764
|
-
if (tokenError) return tokenError;
|
|
765
|
-
|
|
766
|
-
const wsUrl = new URL(req.url);
|
|
767
|
-
const callSessionId = wsUrl.searchParams.get("callSessionId");
|
|
768
|
-
if (!callSessionId) {
|
|
769
|
-
return new Response("Missing callSessionId", { status: 400 });
|
|
770
|
-
}
|
|
771
|
-
const upgraded = server.upgrade(req, { data: { callSessionId } });
|
|
772
|
-
if (!upgraded) {
|
|
773
|
-
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
774
|
-
}
|
|
775
|
-
// Bun's WebSocket upgrade consumes the request — no Response is sent.
|
|
776
|
-
return undefined!;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
724
|
private handleMediaStreamUpgrade(
|
|
780
725
|
req: Request,
|
|
781
726
|
server: ReturnType<typeof Bun.serve>,
|
|
@@ -798,7 +743,7 @@ export class RuntimeHttpServer {
|
|
|
798
743
|
return new Response("Missing callSessionId", { status: 400 });
|
|
799
744
|
}
|
|
800
745
|
// Media-stream connections use a distinct wsType so the open/message/close
|
|
801
|
-
// handlers route them to MediaStreamCallSession
|
|
746
|
+
// handlers route them to MediaStreamCallSession.
|
|
802
747
|
const upgraded = server.upgrade(req, {
|
|
803
748
|
data: {
|
|
804
749
|
wsType: "media-stream",
|
|
@@ -815,7 +760,7 @@ export class RuntimeHttpServer {
|
|
|
815
760
|
/**
|
|
816
761
|
* Handle WebSocket upgrade for `/v1/stt/stream`.
|
|
817
762
|
*
|
|
818
|
-
* Private-network restrictions apply (same as
|
|
763
|
+
* Private-network restrictions apply (same as media-stream) so the
|
|
819
764
|
* runtime remains unreachable from the public internet. The gateway
|
|
820
765
|
* authenticates the downstream client and proxies the upgrade with a
|
|
821
766
|
* short-lived gateway service token.
|
|
@@ -1071,8 +1016,6 @@ export class RuntimeHttpServer {
|
|
|
1071
1016
|
return await handleVoiceWebhook(validatedReq);
|
|
1072
1017
|
if (twilioSubpath === "status")
|
|
1073
1018
|
return await handleStatusCallback(validatedReq);
|
|
1074
|
-
if (twilioSubpath === "connect-action")
|
|
1075
|
-
return await handleConnectAction(validatedReq);
|
|
1076
1019
|
|
|
1077
1020
|
return null;
|
|
1078
1021
|
}
|