@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,22 +1,96 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Assistant Events --
|
|
2
|
+
* Assistant Events -- shared envelope type, SSE framing helpers, and the
|
|
3
|
+
* daemon-side specialization.
|
|
3
4
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* callers continue to get full discriminated-union narrowing.
|
|
5
|
+
* The generic `BaseAssistantEvent<TMessage>` envelope and its framing
|
|
6
|
+
* helpers carry no daemon imports. This file pins the generic payload to
|
|
7
|
+
* the daemon-side `ServerMessage` union so existing callers continue to get
|
|
8
|
+
* full discriminated-union narrowing.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import
|
|
12
|
-
import { buildAssistantEvent as baseBuildAssistantEvent } from "@vellumai/skill-host-contracts";
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
13
12
|
|
|
14
13
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// -- Generic base --------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A single assistant event wrapping an outbound message payload.
|
|
19
|
+
*
|
|
20
|
+
* Generic over the payload type. The `TMessage` default of `unknown` keeps
|
|
21
|
+
* the envelope nameable without a type argument when the caller does not
|
|
22
|
+
* care about message narrowing.
|
|
23
|
+
*/
|
|
24
|
+
interface BaseAssistantEvent<TMessage = unknown> {
|
|
25
|
+
/** Globally unique event identifier (UUID). */
|
|
26
|
+
id: string;
|
|
27
|
+
/** Resolved conversation id when available. */
|
|
28
|
+
conversationId?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Monotonic per-conversation sequence number. Assigned by the daemon at
|
|
31
|
+
* publish time for conversation-scoped events; absent for unscoped
|
|
32
|
+
* broadcasts. Clients track the highest observed `seq` per conversation
|
|
33
|
+
* and pass it back on reconnect to request replay of missed events.
|
|
34
|
+
*/
|
|
35
|
+
seq?: number;
|
|
36
|
+
/** ISO-8601 timestamp of when the event was emitted. */
|
|
37
|
+
emittedAt: string;
|
|
38
|
+
/** Outbound message payload. */
|
|
39
|
+
message: TMessage;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Construct a `BaseAssistantEvent` envelope around a message payload.
|
|
44
|
+
*
|
|
45
|
+
* @param message The outbound message payload.
|
|
46
|
+
* @param conversationId Optional conversation id -- pass when known.
|
|
47
|
+
*/
|
|
48
|
+
function baseBuildAssistantEvent<TMessage>(
|
|
49
|
+
message: TMessage,
|
|
50
|
+
conversationId?: string,
|
|
51
|
+
): BaseAssistantEvent<TMessage> {
|
|
52
|
+
return {
|
|
53
|
+
id: randomUUID(),
|
|
54
|
+
conversationId,
|
|
55
|
+
emittedAt: new Date().toISOString(),
|
|
56
|
+
message,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// -- SSE framing ---------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Format an AssistantEvent as a Server-Sent Events frame.
|
|
64
|
+
*
|
|
65
|
+
* The SSE spec (https://html.spec.whatwg.org/multipage/server-sent-events.html)
|
|
66
|
+
* requires each field on its own line with a trailing blank line.
|
|
67
|
+
*
|
|
68
|
+
* ```
|
|
69
|
+
* event: assistant_event\n
|
|
70
|
+
* id: <event.id>\n
|
|
71
|
+
* data: <JSON>\n
|
|
72
|
+
* \n
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* The SSE `id:` line is the per-event UUID and is intentionally decoupled
|
|
76
|
+
* from any replay cursor. Replay-aware consumers read `seq` from the JSON
|
|
77
|
+
* payload of the envelope itself.
|
|
78
|
+
*/
|
|
79
|
+
export function formatSseFrame(event: BaseAssistantEvent): string {
|
|
80
|
+
const sanitizedId = event.id.replace(/[\n\r]/g, "");
|
|
81
|
+
const data = JSON.stringify(event);
|
|
82
|
+
return `event: assistant_event\nid: ${sanitizedId}\ndata: ${data}\n\n`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Format a keep-alive SSE comment.
|
|
87
|
+
* Clients should ignore comment lines (`:`) per the SSE spec.
|
|
88
|
+
*/
|
|
89
|
+
export function formatSseHeartbeat(): string {
|
|
90
|
+
return ": heartbeat\n\n";
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// -- Daemon-side specialization ------------------------------------------------
|
|
20
94
|
|
|
21
95
|
/** Daemon-side specialization of the generic event envelope. */
|
|
22
96
|
export type AssistantEvent = BaseAssistantEvent<ServerMessage>;
|
|
@@ -242,6 +242,37 @@ describe("ROUTES policy declarations", () => {
|
|
|
242
242
|
expect(route!.policy!.allowedPrincipalTypes).toContain("local");
|
|
243
243
|
});
|
|
244
244
|
|
|
245
|
+
test("contacts/invites/:id/call is gateway-only", async () => {
|
|
246
|
+
// The handler dials whatever number the body supplies — the invite
|
|
247
|
+
// validation lives in the gateway's triggerInviteCallNative, so an
|
|
248
|
+
// actor-reachable policy would be an arbitrary-outbound-call primitive.
|
|
249
|
+
const { ROUTES } = await import("../../routes/index.js");
|
|
250
|
+
const route = ROUTES.find((r) => r.operationId === "invites_trigger_call");
|
|
251
|
+
expect(route).toBeDefined();
|
|
252
|
+
expect(route!.policy).not.toBeNull();
|
|
253
|
+
expect(route!.policy!.allowedPrincipalTypes).toEqual(["svc_gateway"]);
|
|
254
|
+
expect(route!.policy!.requiredScopes).toContain("internal.write");
|
|
255
|
+
|
|
256
|
+
// An actor principal with settings.write is denied.
|
|
257
|
+
authDisabled = false;
|
|
258
|
+
const actorCtx = buildTestContext({
|
|
259
|
+
principalType: "actor",
|
|
260
|
+
scopes: ["settings.write"],
|
|
261
|
+
});
|
|
262
|
+
const denied = enforcePolicy(route!.endpoint, route!.policy!, actorCtx);
|
|
263
|
+
expect(denied).not.toBeNull();
|
|
264
|
+
expect(denied!.status).toBe(403);
|
|
265
|
+
|
|
266
|
+
// The gateway service principal with internal.write is allowed.
|
|
267
|
+
const gatewayCtx = buildTestContext({
|
|
268
|
+
principalType: "svc_gateway",
|
|
269
|
+
scopes: ["internal.write"],
|
|
270
|
+
});
|
|
271
|
+
expect(
|
|
272
|
+
enforcePolicy(route!.endpoint, route!.policy!, gatewayCtx),
|
|
273
|
+
).toBeNull();
|
|
274
|
+
});
|
|
275
|
+
|
|
245
276
|
test("internal/oauth/connect/start is gateway-only", async () => {
|
|
246
277
|
const { ROUTES } = await import("../../routes/index.js");
|
|
247
278
|
const route = ROUTES.find(
|
|
@@ -27,8 +27,58 @@ export {
|
|
|
27
27
|
// Approval actions (daemon-internal)
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* The set of actions a user can take on an approval prompt.
|
|
32
|
+
*
|
|
33
|
+
* `approve_once` / `reject` are the generic decision pair used by every
|
|
34
|
+
* request kind. `trust` / `verify_code` / `leave_unverified` / `block` are the
|
|
35
|
+
* introduction-card actions, valid only for `access_request` requests — the
|
|
36
|
+
* canonical decision primitive rejects them for any other kind.
|
|
37
|
+
*/
|
|
38
|
+
export const APPROVAL_ACTION_IDS = [
|
|
39
|
+
"approve_once",
|
|
40
|
+
"reject",
|
|
41
|
+
"trust",
|
|
42
|
+
"verify_code",
|
|
43
|
+
"leave_unverified",
|
|
44
|
+
"block",
|
|
45
|
+
] as const;
|
|
46
|
+
|
|
47
|
+
export type ApprovalAction = (typeof APPROVAL_ACTION_IDS)[number];
|
|
48
|
+
|
|
49
|
+
/** All valid approval action ids, for wire-input validation. */
|
|
50
|
+
export const APPROVAL_ACTION_SET: ReadonlySet<string> = new Set(
|
|
51
|
+
APPROVAL_ACTION_IDS,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Type predicate tying the runtime membership check to the `ApprovalAction`
|
|
56
|
+
* type, so wire-input validation sites never need an `as` cast.
|
|
57
|
+
*/
|
|
58
|
+
export function isApprovalAction(value: string): value is ApprovalAction {
|
|
59
|
+
return APPROVAL_ACTION_SET.has(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Introduction-card actions. Only meaningful for `access_request` requests:
|
|
64
|
+
* the guardian sets the contact's trust level directly on the card.
|
|
65
|
+
*/
|
|
66
|
+
export const INTRODUCTION_ACTION_SET: ReadonlySet<string> = new Set([
|
|
67
|
+
"trust",
|
|
68
|
+
"verify_code",
|
|
69
|
+
"leave_unverified",
|
|
70
|
+
"block",
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Actions that resolve a request to the `denied` terminal status. Everything
|
|
75
|
+
* else resolves to `approved`.
|
|
76
|
+
*/
|
|
77
|
+
export const DENYING_ACTION_SET: ReadonlySet<string> = new Set([
|
|
78
|
+
"reject",
|
|
79
|
+
"leave_unverified",
|
|
80
|
+
"block",
|
|
81
|
+
]);
|
|
32
82
|
|
|
33
83
|
/**
|
|
34
84
|
* Map `GuardianDecisionAction[]` to `ApprovalActionOption[]` so channel
|
|
@@ -18,7 +18,10 @@ import type {
|
|
|
18
18
|
ApprovalUIMetadata,
|
|
19
19
|
ChannelApprovalPrompt,
|
|
20
20
|
} from "./channel-approval-types.js";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
DENYING_ACTION_SET,
|
|
23
|
+
toApprovalActionOptions,
|
|
24
|
+
} from "./channel-approval-types.js";
|
|
22
25
|
import {
|
|
23
26
|
buildOneTimeDecisionActions,
|
|
24
27
|
buildPlainTextFallback,
|
|
@@ -47,7 +50,9 @@ export function getChannelApprovalPrompt(
|
|
|
47
50
|
conversationId: string,
|
|
48
51
|
): ChannelApprovalPrompt | null {
|
|
49
52
|
const pending = getApprovalInfoByConversation(conversationId);
|
|
50
|
-
if (pending.length === 0)
|
|
53
|
+
if (pending.length === 0) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
51
56
|
|
|
52
57
|
// Use the first pending interaction — channel UIs show one prompt at a time.
|
|
53
58
|
const info = pending[0];
|
|
@@ -126,10 +131,12 @@ export function buildApprovalUIMetadata(
|
|
|
126
131
|
|
|
127
132
|
/**
|
|
128
133
|
* Map a channel-level `ApprovalAction` to the permission system's
|
|
129
|
-
* `UserDecision` type.
|
|
134
|
+
* `UserDecision` type. Every deny-intent action (reject, leave_unverified,
|
|
135
|
+
* block) maps to `deny` — a deny-flavored callback must never resolve a
|
|
136
|
+
* pending tool confirmation as an approval.
|
|
130
137
|
*/
|
|
131
138
|
function mapApprovalActionToUserDecision(action: ApprovalAction): UserDecision {
|
|
132
|
-
return action
|
|
139
|
+
return DENYING_ACTION_SET.has(action) ? "deny" : "allow";
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
// ---------------------------------------------------------------------------
|
|
@@ -151,24 +158,32 @@ export function handleChannelDecision(
|
|
|
151
158
|
decisionContext?: string,
|
|
152
159
|
): HandleDecisionResult {
|
|
153
160
|
const pending = getApprovalInfoByConversation(conversationId);
|
|
154
|
-
if (pending.length === 0)
|
|
161
|
+
if (pending.length === 0) {
|
|
162
|
+
return { applied: false };
|
|
163
|
+
}
|
|
155
164
|
|
|
156
165
|
// Callback-based decisions include a request ID and must resolve to that exact
|
|
157
166
|
// pending confirmation. Plain-text decisions still apply to the first prompt.
|
|
158
167
|
const info = decision.requestId
|
|
159
168
|
? pending.find((candidate) => candidate.requestId === decision.requestId)
|
|
160
169
|
: pending[0];
|
|
161
|
-
if (!info)
|
|
170
|
+
if (!info) {
|
|
171
|
+
return { applied: false };
|
|
172
|
+
}
|
|
162
173
|
|
|
163
174
|
// Peek (not consume) — resolveConfirmation() owns deregistration and
|
|
164
175
|
// must fire the promptResolve callback stored in the interaction.
|
|
165
176
|
const resolved = pendingInteractions.get(info.requestId);
|
|
166
|
-
if (!resolved)
|
|
177
|
+
if (!resolved) {
|
|
178
|
+
return { applied: false };
|
|
179
|
+
}
|
|
167
180
|
|
|
168
181
|
// Map channel-level action to the permission system's UserDecision type.
|
|
169
182
|
const userDecision = mapApprovalActionToUserDecision(decision.action);
|
|
170
183
|
const conversation = findConversation(resolved.conversationId);
|
|
171
|
-
if (!conversation)
|
|
184
|
+
if (!conversation) {
|
|
185
|
+
return { applied: false };
|
|
186
|
+
}
|
|
172
187
|
|
|
173
188
|
conversation.handleConfirmationResponse(info.requestId, userDecision, {
|
|
174
189
|
decisionContext,
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* channel.
|
|
9
9
|
*
|
|
10
10
|
* All methods are optional — the adapter layer is intentionally thin.
|
|
11
|
-
* Redemption
|
|
12
|
-
* instruction generation lives in `invite-instruction-generator.ts`.
|
|
11
|
+
* Redemption is gateway-native (gateway/src/verification/invite-redemption.ts)
|
|
12
|
+
* and invite instruction generation lives in `invite-instruction-generator.ts`.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { ChannelId } from "../channels/types.js";
|
|
@@ -45,7 +45,7 @@ export const voiceInviteAdapter: ChannelInviteAdapter = {
|
|
|
45
45
|
sourceMetadata?: import("@vellumai/gateway-client").SourceMetadata;
|
|
46
46
|
}): string | undefined {
|
|
47
47
|
// Voice invite redemption bypasses generic token extraction — it uses
|
|
48
|
-
// the identity-bound voice-code
|
|
48
|
+
// the gateway's identity-bound voice-code redemption engine.
|
|
49
49
|
return undefined;
|
|
50
50
|
},
|
|
51
51
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isInviteCodeRedemptionEnabled } from "@vellumai/gateway-client";
|
|
1
2
|
import {
|
|
2
3
|
normalizePublicBaseUrl,
|
|
3
4
|
resolveTwilioPublicBaseUrl,
|
|
@@ -5,7 +6,6 @@ import {
|
|
|
5
6
|
|
|
6
7
|
import { resolveTwilioPhoneNumber } from "../calls/twilio-config.js";
|
|
7
8
|
import { hasTwilioCredentials } from "../calls/twilio-rest.js";
|
|
8
|
-
import { getChannelInvitePolicy } from "../channels/config.js";
|
|
9
9
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
10
10
|
import { getNestedValue, loadRawConfig } from "../config/loader.js";
|
|
11
11
|
import { credentialKey } from "../security/credential-key.js";
|
|
@@ -168,7 +168,6 @@ const telegramProbe: ChannelProbe = {
|
|
|
168
168
|
const emailProbe: ChannelProbe = {
|
|
169
169
|
channel: "email",
|
|
170
170
|
async runLocalChecks(): Promise<ReadinessCheckResult[]> {
|
|
171
|
-
const invitePolicy = getChannelInvitePolicy("email");
|
|
172
171
|
return [
|
|
173
172
|
check(
|
|
174
173
|
"platform_email",
|
|
@@ -178,7 +177,7 @@ const emailProbe: ChannelProbe = {
|
|
|
178
177
|
),
|
|
179
178
|
check(
|
|
180
179
|
"invite_policy",
|
|
181
|
-
|
|
180
|
+
isInviteCodeRedemptionEnabled("email"),
|
|
182
181
|
"Email invite code redemption is enabled",
|
|
183
182
|
"Email invite code redemption is disabled",
|
|
184
183
|
),
|
|
@@ -218,7 +217,6 @@ const whatsappProbe: ChannelProbe = {
|
|
|
218
217
|
channel: "whatsapp",
|
|
219
218
|
async runLocalChecks(): Promise<ReadinessCheckResult[]> {
|
|
220
219
|
const displayNumber = resolveWhatsAppDisplayNumber();
|
|
221
|
-
const invitePolicy = getChannelInvitePolicy("whatsapp");
|
|
222
220
|
return [
|
|
223
221
|
await checkCredential(
|
|
224
222
|
"whatsapp_phone_number_id",
|
|
@@ -252,7 +250,7 @@ const whatsappProbe: ChannelProbe = {
|
|
|
252
250
|
),
|
|
253
251
|
check(
|
|
254
252
|
"invite_policy",
|
|
255
|
-
|
|
253
|
+
isInviteCodeRedemptionEnabled("whatsapp"),
|
|
256
254
|
"WhatsApp invite code redemption is enabled",
|
|
257
255
|
"WhatsApp invite code redemption is disabled",
|
|
258
256
|
),
|
|
@@ -11,11 +11,7 @@ import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
|
|
|
11
11
|
import { classifyDiskPressureTurnPolicy } from "../daemon/disk-pressure-policy.js";
|
|
12
12
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
13
13
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
14
|
-
import {
|
|
15
|
-
addSlackDmLiveDeliveredTextResponseIndex,
|
|
16
|
-
getSlackDmLiveDeliveredTextResponseIndexes,
|
|
17
|
-
updateDeliveredSegmentCount,
|
|
18
|
-
} from "../persistence/delivery-channels.js";
|
|
14
|
+
import { updateDeliveredSegmentCount } from "../persistence/delivery-channels.js";
|
|
19
15
|
import {
|
|
20
16
|
clearPayload,
|
|
21
17
|
linkMessage,
|
|
@@ -38,7 +34,6 @@ import {
|
|
|
38
34
|
import { finalizeEventDelivery } from "./finalize-event-delivery.js";
|
|
39
35
|
import { deliverChannelReply } from "./gateway-client.js";
|
|
40
36
|
import type { MessageProcessor } from "./http-types.js";
|
|
41
|
-
import { createSlackDmTextDeliveryController } from "./slack-dm-text-delivery.js";
|
|
42
37
|
import { resolveRoutingStateFromRuntime } from "./trust-context-resolver.js";
|
|
43
38
|
|
|
44
39
|
const log = getLogger("runtime-http");
|
|
@@ -293,19 +288,13 @@ export async function sweepFailedEvents(
|
|
|
293
288
|
typeof payload.externalChatId === "string"
|
|
294
289
|
? payload.externalChatId
|
|
295
290
|
: undefined;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
deliveredTextResponseIndexes:
|
|
304
|
-
getSlackDmLiveDeliveredTextResponseIndexes(event.id),
|
|
305
|
-
onTextResponseDelivered: (responseIndex) =>
|
|
306
|
-
addSlackDmLiveDeliveredTextResponseIndex(event.id, responseIndex),
|
|
307
|
-
})
|
|
308
|
-
: undefined;
|
|
291
|
+
// A retry never opens a new stream: a prior attempt may already have
|
|
292
|
+
// streamed a message, so re-streaming would duplicate the reply. The
|
|
293
|
+
// durable delivery below edits that message in place when one exists.
|
|
294
|
+
const priorStreamMessageTs =
|
|
295
|
+
typeof payload.slackStreamMessageTs === "string"
|
|
296
|
+
? payload.slackStreamMessageTs
|
|
297
|
+
: undefined;
|
|
309
298
|
let replyMessageId: string | undefined;
|
|
310
299
|
const observeAgentEvent = (msg: ServerMessage): void => {
|
|
311
300
|
if (
|
|
@@ -315,7 +304,6 @@ export async function sweepFailedEvents(
|
|
|
315
304
|
) {
|
|
316
305
|
replyMessageId = msg.messageId;
|
|
317
306
|
}
|
|
318
|
-
slackDmTextDelivery?.observeEvent(msg);
|
|
319
307
|
};
|
|
320
308
|
|
|
321
309
|
let userMessageId: string | undefined;
|
|
@@ -349,9 +337,6 @@ export async function sweepFailedEvents(
|
|
|
349
337
|
);
|
|
350
338
|
} catch (err) {
|
|
351
339
|
log.error({ err, eventId: event.id }, "Retry failed for channel event");
|
|
352
|
-
if (slackDmTextDelivery) {
|
|
353
|
-
await slackDmTextDelivery.waitForPendingDeliveries();
|
|
354
|
-
}
|
|
355
340
|
recordProcessingFailure(event.id, err);
|
|
356
341
|
continue;
|
|
357
342
|
}
|
|
@@ -366,7 +351,8 @@ export async function sweepFailedEvents(
|
|
|
366
351
|
assistantId,
|
|
367
352
|
replyMessageId,
|
|
368
353
|
userMessageId,
|
|
369
|
-
|
|
354
|
+
slackReplySession: undefined,
|
|
355
|
+
priorStreamMessageTs,
|
|
370
356
|
});
|
|
371
357
|
} catch (err) {
|
|
372
358
|
log.error(
|
|
@@ -411,6 +397,13 @@ export async function sweepFailedEvents(
|
|
|
411
397
|
: undefined;
|
|
412
398
|
const assistantId =
|
|
413
399
|
typeof payload.assistantId === "string" ? payload.assistantId : undefined;
|
|
400
|
+
// A prior attempt may already have streamed a message; its first
|
|
401
|
+
// undelivered segment edits that message in place rather than posting a
|
|
402
|
+
// duplicate reply beside it.
|
|
403
|
+
const priorStreamMessageTs =
|
|
404
|
+
typeof payload.slackStreamMessageTs === "string"
|
|
405
|
+
? payload.slackStreamMessageTs
|
|
406
|
+
: undefined;
|
|
414
407
|
if (!replyCallbackUrl || !externalChatId) {
|
|
415
408
|
recordDeliveryFailure(
|
|
416
409
|
event.id,
|
|
@@ -444,6 +437,7 @@ export async function sweepFailedEvents(
|
|
|
444
437
|
{
|
|
445
438
|
messageId: replyMessageId,
|
|
446
439
|
startFromSegment: event.deliveredSegmentCount,
|
|
440
|
+
...(priorStreamMessageTs ? { messageTs: priorStreamMessageTs } : {}),
|
|
447
441
|
onSegmentDelivered: (count) =>
|
|
448
442
|
updateDeliveredSegmentCount(event.id, count),
|
|
449
443
|
},
|
|
@@ -31,7 +31,6 @@ import {
|
|
|
31
31
|
updateSessionDelivery as storeUpdateSessionDelivery,
|
|
32
32
|
updateSessionStatus as storeUpdateSessionStatus,
|
|
33
33
|
} from "../channels/channel-verification-sessions.js";
|
|
34
|
-
import { revokeGuardianBinding } from "../contacts/contacts-write.js";
|
|
35
34
|
import {
|
|
36
35
|
getGuardianDelivery,
|
|
37
36
|
getGuardianDeliveryFresh,
|
|
@@ -48,8 +47,12 @@ import { composeApprovalMessage } from "./approval-message-composer.js";
|
|
|
48
47
|
// Constants
|
|
49
48
|
// ---------------------------------------------------------------------------
|
|
50
49
|
|
|
51
|
-
/**
|
|
52
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Challenge TTL in milliseconds (10 minutes). Exported so consumers that
|
|
52
|
+
* reason about "is a just-issued code still redeemable" (e.g. the
|
|
53
|
+
* access-request handshake window) share this exact bound.
|
|
54
|
+
*/
|
|
55
|
+
export const CHALLENGE_TTL_MS = 10 * 60 * 1000;
|
|
53
56
|
|
|
54
57
|
/** Maximum invalid verification attempts within the throttling window before lockout. */
|
|
55
58
|
const RATE_LIMIT_MAX_ATTEMPTS = 5;
|
|
@@ -342,7 +345,9 @@ export async function getGuardianBinding(
|
|
|
342
345
|
channel,
|
|
343
346
|
guardianExternalUserId: delivery.address,
|
|
344
347
|
guardianDeliveryChatId: delivery.externalChatId ?? "",
|
|
345
|
-
|
|
348
|
+
// A missing principal is surfaced as null (unresolved), never coerced to
|
|
349
|
+
// an empty string that would masquerade as a present-but-empty principal.
|
|
350
|
+
guardianPrincipalId: delivery.principalId ?? null,
|
|
346
351
|
status: "active" as const,
|
|
347
352
|
verifiedAt: delivery.verifiedAt ?? 0,
|
|
348
353
|
// verifiedVia is not carried on the delivery contract; a bound guardian
|
|
@@ -390,13 +395,6 @@ export async function isGuardian(
|
|
|
390
395
|
return delivery.address.toLowerCase() === address.toLowerCase();
|
|
391
396
|
}
|
|
392
397
|
|
|
393
|
-
/**
|
|
394
|
-
* Revoke the active guardian binding for a given assistant and channel.
|
|
395
|
-
*/
|
|
396
|
-
export function revokeBinding(assistantId: string, channel: string): boolean {
|
|
397
|
-
return revokeGuardianBinding(channel);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
398
|
/**
|
|
401
399
|
* Revoke all pending sessions for a given channel.
|
|
402
400
|
* Called when the user cancels verification so that stale sessions
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
recordDeliveryFailure,
|
|
5
5
|
} from "../persistence/delivery-status.js";
|
|
6
6
|
import { deliverReplyViaCallback } from "./channel-reply-delivery.js";
|
|
7
|
-
import type {
|
|
7
|
+
import type { SlackReplySession } from "./slack-reply-session.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Owns the complete delivery-after-processing sequence for a channel
|
|
11
|
-
* inbound event:
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* inbound event: finalizes any live Slack stream, persists the segment
|
|
12
|
+
* baseline so delivery-only retries resume correctly, delivers remaining
|
|
13
|
+
* content + attachments, and transitions the event to its terminal delivery
|
|
14
|
+
* state.
|
|
15
15
|
*
|
|
16
16
|
* Both the primary dispatch path and the processing-retry path call this
|
|
17
17
|
* function. The delivery-only retry path does NOT use this function — it
|
|
@@ -26,7 +26,13 @@ export async function finalizeEventDelivery(params: {
|
|
|
26
26
|
assistantId: string | undefined;
|
|
27
27
|
replyMessageId: string | undefined;
|
|
28
28
|
userMessageId: string | undefined;
|
|
29
|
-
|
|
29
|
+
slackReplySession: SlackReplySession | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* `ts` of a Slack message streamed on a previous, failed attempt. A retry
|
|
32
|
+
* has no live stream of its own, so it edits this message in place rather
|
|
33
|
+
* than posting a duplicate reply.
|
|
34
|
+
*/
|
|
35
|
+
priorStreamMessageTs?: string;
|
|
30
36
|
}): Promise<void> {
|
|
31
37
|
const {
|
|
32
38
|
eventId,
|
|
@@ -36,16 +42,26 @@ export async function finalizeEventDelivery(params: {
|
|
|
36
42
|
assistantId,
|
|
37
43
|
replyMessageId,
|
|
38
44
|
userMessageId,
|
|
39
|
-
|
|
45
|
+
slackReplySession,
|
|
46
|
+
priorStreamMessageTs,
|
|
40
47
|
} = params;
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
const reconciliation = await slackReplySession?.finish();
|
|
50
|
+
|
|
51
|
+
// A streamed reply already delivered its text live into a single message;
|
|
52
|
+
// durable delivery skips that text, reconciles `slackMeta.channelTs` to the
|
|
53
|
+
// stream `ts`, and posts only attachments. A retry reuses the prior attempt's
|
|
54
|
+
// streamed message, re-delivering the full reply with its first segment
|
|
55
|
+
// editing that message. A plain turn delivers the full reply from segment 0.
|
|
56
|
+
const startFromSegment =
|
|
57
|
+
reconciliation?.mode === "streamed"
|
|
58
|
+
? reconciliation.deliveredSegmentCount
|
|
59
|
+
: 0;
|
|
60
|
+
const streamMessageTs =
|
|
61
|
+
reconciliation?.mode === "streamed"
|
|
62
|
+
? reconciliation.messageTs
|
|
63
|
+
: priorStreamMessageTs;
|
|
45
64
|
|
|
46
|
-
const resumeOptions =
|
|
47
|
-
slackDmTextDelivery?.getFinalDeliveryResumeOptions(replyMessageId);
|
|
48
|
-
const startFromSegment = resumeOptions?.startFromSegment ?? 0;
|
|
49
65
|
try {
|
|
50
66
|
updateDeliveredSegmentCount(eventId, startFromSegment);
|
|
51
67
|
await deliverReplyViaCallback(
|
|
@@ -57,9 +73,7 @@ export async function finalizeEventDelivery(params: {
|
|
|
57
73
|
messageId: replyMessageId,
|
|
58
74
|
sinceMessageId: userMessageId,
|
|
59
75
|
startFromSegment,
|
|
60
|
-
...(
|
|
61
|
-
? { messageTs: resumeOptions.messageTs }
|
|
62
|
-
: {}),
|
|
76
|
+
...(streamMessageTs ? { messageTs: streamMessageTs } : {}),
|
|
63
77
|
onSegmentDelivered: (count) =>
|
|
64
78
|
updateDeliveredSegmentCount(eventId, count),
|
|
65
79
|
},
|
|
@@ -11,18 +11,15 @@ import {
|
|
|
11
11
|
getCanonicalGuardianRequest,
|
|
12
12
|
isRequestInConversationScope,
|
|
13
13
|
} from "../contacts/canonical-guardian-store.js";
|
|
14
|
-
import
|
|
14
|
+
import {
|
|
15
|
+
APPROVAL_ACTION_IDS,
|
|
16
|
+
isApprovalAction,
|
|
17
|
+
} from "./channel-approval-types.js";
|
|
15
18
|
|
|
16
19
|
// ---------------------------------------------------------------------------
|
|
17
20
|
// Constants
|
|
18
21
|
// ---------------------------------------------------------------------------
|
|
19
22
|
|
|
20
|
-
/** Canonical set of valid guardian actions, shared across all entrypoints. */
|
|
21
|
-
const VALID_GUARDIAN_ACTIONS: ReadonlySet<string> = new Set<string>([
|
|
22
|
-
"approve_once",
|
|
23
|
-
"reject",
|
|
24
|
-
]);
|
|
25
|
-
|
|
26
23
|
/**
|
|
27
24
|
* Legacy actions that map to canonical ones during client rollout.
|
|
28
25
|
* All temporal/persistent approval variants collapse to approve_once.
|
|
@@ -71,7 +68,9 @@ export type ProcessGuardianDecisionResult =
|
|
|
71
68
|
* canonical decision, and maps the result to a caller-agnostic shape that
|
|
72
69
|
* both HTTP and message handlers can interpret.
|
|
73
70
|
*
|
|
74
|
-
*
|
|
71
|
+
* Valid actions are the `ApprovalAction` union; the canonical primitive
|
|
72
|
+
* additionally scopes the introduction-card actions to `access_request`
|
|
73
|
+
* requests.
|
|
75
74
|
*/
|
|
76
75
|
export async function processGuardianDecision(
|
|
77
76
|
params: ProcessGuardianDecisionParams,
|
|
@@ -80,11 +79,11 @@ export async function processGuardianDecision(
|
|
|
80
79
|
|
|
81
80
|
// 1. Canonicalize legacy actions, then validate
|
|
82
81
|
const action = LEGACY_ACTION_MAP[params.action] ?? params.action;
|
|
83
|
-
if (!
|
|
82
|
+
if (!isApprovalAction(action)) {
|
|
84
83
|
return {
|
|
85
84
|
ok: false,
|
|
86
85
|
error: "invalid_action",
|
|
87
|
-
message: `Invalid action: ${params.action}. Must be one of:
|
|
86
|
+
message: `Invalid action: ${params.action}. Must be one of: ${APPROVAL_ACTION_IDS.join(", ")}`,
|
|
88
87
|
};
|
|
89
88
|
}
|
|
90
89
|
|
|
@@ -105,7 +104,7 @@ export async function processGuardianDecision(
|
|
|
105
104
|
// 3. Apply the canonical decision
|
|
106
105
|
const canonicalResult = await applyCanonicalGuardianDecision({
|
|
107
106
|
requestId,
|
|
108
|
-
action
|
|
107
|
+
action,
|
|
109
108
|
actorContext: {
|
|
110
109
|
actorPrincipalId: actorContext.actorPrincipalId,
|
|
111
110
|
actorExternalUserId: undefined, // Desktop path — no channel-native ID
|