@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022248.91fa053
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/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
|
@@ -17,68 +17,6 @@ import type {
|
|
|
17
17
|
TelephonySttMode,
|
|
18
18
|
} from "../../stt/types.js";
|
|
19
19
|
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Telephony routing metadata
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Strategy kind for telephony call setup.
|
|
26
|
-
*
|
|
27
|
-
* Determines how the telephony routing resolver (`telephony-stt-routing.ts`)
|
|
28
|
-
* wires the STT provider into a Twilio call:
|
|
29
|
-
*
|
|
30
|
-
* - `"conversation-relay-native"` — the provider is natively supported by
|
|
31
|
-
* Twilio ConversationRelay. TwiML includes `transcriptionProvider` /
|
|
32
|
-
* `speechModel` attributes and Twilio handles audio ingestion.
|
|
33
|
-
* - `"media-stream-custom"` — the provider is not natively supported by
|
|
34
|
-
* Twilio. A `<Stream>` media-stream is opened and the daemon transcribes
|
|
35
|
-
* audio server-side via the provider's batch API.
|
|
36
|
-
*/
|
|
37
|
-
type TelephonyStrategyKind =
|
|
38
|
-
| "conversation-relay-native"
|
|
39
|
-
| "media-stream-custom";
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Twilio-native ConversationRelay provider name.
|
|
43
|
-
*
|
|
44
|
-
* These are the values Twilio accepts in the `transcriptionProvider` TwiML
|
|
45
|
-
* attribute on `<ConversationRelay>`.
|
|
46
|
-
*/
|
|
47
|
-
export type TwilioNativeProvider = "Deepgram" | "Google";
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Twilio-native mapping details for providers routed through
|
|
51
|
-
* ConversationRelay. Only present when `strategyKind` is
|
|
52
|
-
* `"conversation-relay-native"`.
|
|
53
|
-
*/
|
|
54
|
-
interface TwilioNativeMapping {
|
|
55
|
-
/** Twilio-native provider name for the TwiML `transcriptionProvider` attribute. */
|
|
56
|
-
readonly provider: TwilioNativeProvider;
|
|
57
|
-
/**
|
|
58
|
-
* Default ASR speech model identifier, or `undefined` to use the
|
|
59
|
-
* provider's default model. Individual providers override as needed
|
|
60
|
-
* (e.g. Deepgram defaults to `"nova-3"`).
|
|
61
|
-
*/
|
|
62
|
-
readonly defaultSpeechModel: string | undefined;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Telephony routing metadata — the single source of truth for how a
|
|
67
|
-
* provider is wired into Twilio call setup.
|
|
68
|
-
*
|
|
69
|
-
* The telephony routing resolver reads these fields from the catalog
|
|
70
|
-
* instead of maintaining its own hardcoded maps.
|
|
71
|
-
*/
|
|
72
|
-
interface TelephonyRouting {
|
|
73
|
-
/** Which Twilio call-setup strategy this provider uses. */
|
|
74
|
-
readonly strategyKind: TelephonyStrategyKind;
|
|
75
|
-
/**
|
|
76
|
-
* Twilio-native mapping details. Present when `strategyKind` is
|
|
77
|
-
* `"conversation-relay-native"`, absent for `"media-stream-custom"`.
|
|
78
|
-
*/
|
|
79
|
-
readonly twilioNativeMapping?: TwilioNativeMapping;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
20
|
// ---------------------------------------------------------------------------
|
|
83
21
|
// Client display metadata
|
|
84
22
|
// ---------------------------------------------------------------------------
|
|
@@ -161,13 +99,6 @@ interface SttProviderEntry {
|
|
|
161
99
|
*/
|
|
162
100
|
readonly supportsDiarization: boolean;
|
|
163
101
|
|
|
164
|
-
/**
|
|
165
|
-
* Telephony routing metadata — describes how this provider is wired
|
|
166
|
-
* into Twilio call setup. This is the single source of truth for
|
|
167
|
-
* strategy selection and Twilio-native mapping details.
|
|
168
|
-
*/
|
|
169
|
-
readonly telephonyRouting: TelephonyRouting;
|
|
170
|
-
|
|
171
102
|
/** Guide for obtaining API credentials from this provider. */
|
|
172
103
|
readonly credentialsGuide?: SttCredentialsGuide;
|
|
173
104
|
}
|
|
@@ -206,13 +137,6 @@ const CATALOG: ReadonlyMap<SttProviderId, SttProviderEntry> = new Map<
|
|
|
206
137
|
telephonyMode: "realtime-ws",
|
|
207
138
|
conversationStreamingMode: "realtime-ws",
|
|
208
139
|
supportsDiarization: true,
|
|
209
|
-
telephonyRouting: {
|
|
210
|
-
strategyKind: "conversation-relay-native",
|
|
211
|
-
twilioNativeMapping: {
|
|
212
|
-
provider: "Deepgram",
|
|
213
|
-
defaultSpeechModel: "nova-3",
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
140
|
credentialsGuide: {
|
|
217
141
|
description:
|
|
218
142
|
"Sign in to the Deepgram console, navigate to API Keys, and create a new key.",
|
|
@@ -239,13 +163,6 @@ const CATALOG: ReadonlyMap<SttProviderId, SttProviderEntry> = new Map<
|
|
|
239
163
|
telephonyMode: "batch-only",
|
|
240
164
|
conversationStreamingMode: "realtime-ws",
|
|
241
165
|
supportsDiarization: false,
|
|
242
|
-
telephonyRouting: {
|
|
243
|
-
strategyKind: "conversation-relay-native",
|
|
244
|
-
twilioNativeMapping: {
|
|
245
|
-
provider: "Google",
|
|
246
|
-
defaultSpeechModel: undefined,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
166
|
credentialsGuide: {
|
|
250
167
|
description:
|
|
251
168
|
"Visit Google AI Studio, sign in with your Google account, and create an API key.",
|
|
@@ -271,9 +188,6 @@ const CATALOG: ReadonlyMap<SttProviderId, SttProviderEntry> = new Map<
|
|
|
271
188
|
telephonyMode: "batch-only",
|
|
272
189
|
conversationStreamingMode: "incremental-batch",
|
|
273
190
|
supportsDiarization: false,
|
|
274
|
-
telephonyRouting: {
|
|
275
|
-
strategyKind: "media-stream-custom",
|
|
276
|
-
},
|
|
277
191
|
credentialsGuide: {
|
|
278
192
|
description:
|
|
279
193
|
"Log in to the OpenAI platform, go to API Keys, and generate a new secret key.",
|
|
@@ -299,9 +213,6 @@ const CATALOG: ReadonlyMap<SttProviderId, SttProviderEntry> = new Map<
|
|
|
299
213
|
telephonyMode: "batch-only",
|
|
300
214
|
conversationStreamingMode: "realtime-ws",
|
|
301
215
|
supportsDiarization: true,
|
|
302
|
-
telephonyRouting: {
|
|
303
|
-
strategyKind: "media-stream-custom",
|
|
304
|
-
},
|
|
305
216
|
credentialsGuide: {
|
|
306
217
|
description:
|
|
307
218
|
"Sign in to the xAI console, navigate to API Keys, and create a new key.",
|
|
@@ -260,6 +260,17 @@ export interface ResolveStreamingTranscriberOptions {
|
|
|
260
260
|
* See {@link DiarizePreference} for semantics.
|
|
261
261
|
*/
|
|
262
262
|
diarize?: DiarizePreference;
|
|
263
|
+
/**
|
|
264
|
+
* Emit `final` events only at utterance boundaries. Supported only by
|
|
265
|
+
* providers whose catalog `telephonyMode` is `"realtime-ws"` (Deepgram,
|
|
266
|
+
* where it also enables `utterance_end_ms` endpointing). All other
|
|
267
|
+
* providers resolve to `null` so the caller falls back to per-turn
|
|
268
|
+
* batch transcription — e.g. openai-whisper fires `final` only from
|
|
269
|
+
* `stop()` (end-of-stream, not end-of-utterance) and xAI emits a
|
|
270
|
+
* `final` per committed segment. Used by telephony call ingestion.
|
|
271
|
+
* Default: false.
|
|
272
|
+
*/
|
|
273
|
+
utteranceBoundaryFinals?: boolean;
|
|
263
274
|
}
|
|
264
275
|
|
|
265
276
|
/**
|
|
@@ -277,6 +288,8 @@ export interface ResolveStreamingTranscriberOptions {
|
|
|
277
288
|
* - No credentials are configured for the resolved provider.
|
|
278
289
|
* - No streaming adapter exists for the configured provider.
|
|
279
290
|
* - `diarize` is `"required"` but the configured provider cannot diarize.
|
|
291
|
+
* - `utteranceBoundaryFinals` is set but the configured provider's catalog
|
|
292
|
+
* `telephonyMode` is not `"realtime-ws"`.
|
|
280
293
|
*/
|
|
281
294
|
export async function resolveStreamingTranscriber(
|
|
282
295
|
options: ResolveStreamingTranscriberOptions = {},
|
|
@@ -298,6 +311,26 @@ export async function resolveStreamingTranscriber(
|
|
|
298
311
|
return null;
|
|
299
312
|
}
|
|
300
313
|
|
|
314
|
+
// Boundary-requiring callers (telephony) can only stream on providers
|
|
315
|
+
// whose catalog telephonyMode is "realtime-ws" (Deepgram gates finals on
|
|
316
|
+
// utterance boundaries). Everything else fires `final` either only from
|
|
317
|
+
// stop() — end-of-stream, not end-of-utterance (openai-whisper) — or per
|
|
318
|
+
// committed segment (xAI), so streaming would yield no replies until
|
|
319
|
+
// hangup, or mid-sentence replies. Resolve to null so the caller falls
|
|
320
|
+
// back to per-turn batch transcription.
|
|
321
|
+
if (options.utteranceBoundaryFinals) {
|
|
322
|
+
const telephonyMode = getProviderEntry(
|
|
323
|
+
provider as SttProviderId,
|
|
324
|
+
)?.telephonyMode;
|
|
325
|
+
if (telephonyMode !== "realtime-ws") {
|
|
326
|
+
log.warn(
|
|
327
|
+
{ providerId: provider, telephonyMode },
|
|
328
|
+
"utterance-boundary finals requested but the configured STT provider has no realtime telephony streaming — falling back to batch transcription",
|
|
329
|
+
);
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
301
334
|
// Resolve diarization capability against the catalog. For `"required"`
|
|
302
335
|
// callers, bail early (with a warning) when the configured provider can't
|
|
303
336
|
// diarize so the caller can surface a clear error to the user.
|
|
@@ -323,9 +356,18 @@ export async function resolveStreamingTranscriber(
|
|
|
323
356
|
return createStreamingTranscriber(apiKey, provider as SttProviderId, {
|
|
324
357
|
sampleRate: options.sampleRate,
|
|
325
358
|
diarize: enableDiarization,
|
|
359
|
+
utteranceBoundaryFinals: options.utteranceBoundaryFinals ?? false,
|
|
326
360
|
});
|
|
327
361
|
}
|
|
328
362
|
|
|
363
|
+
/**
|
|
364
|
+
* Deepgram `utterance_end_ms` used when utterance-boundary finals are
|
|
365
|
+
* requested. Deepgram requires >= 1000 ms; this is the pause length after
|
|
366
|
+
* which an `UtteranceEnd` frame confirms the utterance is complete even
|
|
367
|
+
* when `speech_final` endpointing never fired (e.g. background noise).
|
|
368
|
+
*/
|
|
369
|
+
const UTTERANCE_BOUNDARY_END_MS = 1_000;
|
|
370
|
+
|
|
329
371
|
/**
|
|
330
372
|
* Options forwarded to individual streaming adapter constructors.
|
|
331
373
|
*/
|
|
@@ -338,6 +380,13 @@ interface CreateStreamingTranscriberOptions {
|
|
|
338
380
|
* support.
|
|
339
381
|
*/
|
|
340
382
|
diarize?: boolean;
|
|
383
|
+
/**
|
|
384
|
+
* Whether `final` events should be gated on utterance boundaries.
|
|
385
|
+
* Only forwarded to Deepgram; the resolver never sets this for
|
|
386
|
+
* providers without realtime telephony streaming (they resolve to
|
|
387
|
+
* `null` instead).
|
|
388
|
+
*/
|
|
389
|
+
utteranceBoundaryFinals?: boolean;
|
|
341
390
|
}
|
|
342
391
|
|
|
343
392
|
/**
|
|
@@ -361,6 +410,12 @@ async function createStreamingTranscriber(
|
|
|
361
410
|
return new DeepgramRealtimeTranscriber(apiKey, {
|
|
362
411
|
sampleRate: options.sampleRate,
|
|
363
412
|
...(options.diarize ? { diarize: true } : {}),
|
|
413
|
+
...(options.utteranceBoundaryFinals
|
|
414
|
+
? {
|
|
415
|
+
utteranceBoundaryFinals: true,
|
|
416
|
+
utteranceEndMs: UTTERANCE_BOUNDARY_END_MS,
|
|
417
|
+
}
|
|
418
|
+
: {}),
|
|
364
419
|
});
|
|
365
420
|
}
|
|
366
421
|
case "google-gemini": {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { createToolProgressEmitter } from "./tool-progress-events.js";
|
|
4
|
+
import type { ProviderEvent } from "./types.js";
|
|
5
|
+
|
|
6
|
+
describe("createToolProgressEmitter", () => {
|
|
7
|
+
test("flushes the latest throttled argument progress after activity pauses", async () => {
|
|
8
|
+
const events: ProviderEvent[] = [];
|
|
9
|
+
const progress = createToolProgressEmitter((event) => events.push(event));
|
|
10
|
+
|
|
11
|
+
progress.emitInputJsonDelta("call-1", "app_create", '{"a":1}');
|
|
12
|
+
progress.emitInputJsonDelta("call-1", "app_create", '{"a":12}');
|
|
13
|
+
|
|
14
|
+
expect(events).toEqual([
|
|
15
|
+
{
|
|
16
|
+
type: "tool_use_preview_start",
|
|
17
|
+
toolUseId: "call-1",
|
|
18
|
+
toolName: "app_create",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
type: "input_json_delta",
|
|
22
|
+
toolUseId: "call-1",
|
|
23
|
+
toolName: "app_create",
|
|
24
|
+
accumulatedJson: '{"a":1}',
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
await Bun.sleep(180);
|
|
29
|
+
|
|
30
|
+
expect(events).toEqual([
|
|
31
|
+
{
|
|
32
|
+
type: "tool_use_preview_start",
|
|
33
|
+
toolUseId: "call-1",
|
|
34
|
+
toolName: "app_create",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: "input_json_delta",
|
|
38
|
+
toolUseId: "call-1",
|
|
39
|
+
toolName: "app_create",
|
|
40
|
+
accumulatedJson: '{"a":1}',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "input_json_delta",
|
|
44
|
+
toolUseId: "call-1",
|
|
45
|
+
toolName: "app_create",
|
|
46
|
+
accumulatedJson: '{"a":12}',
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ProviderEvent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
const INPUT_JSON_DELTA_EMIT_INTERVAL_MS = 150;
|
|
4
|
+
|
|
5
|
+
export function createToolProgressEmitter(
|
|
6
|
+
onEvent: ((event: ProviderEvent) => void) | undefined,
|
|
7
|
+
): {
|
|
8
|
+
emitPreviewStart: (toolUseId: string, toolName: string) => void;
|
|
9
|
+
emitInputJsonDelta: (
|
|
10
|
+
toolUseId: string,
|
|
11
|
+
toolName: string,
|
|
12
|
+
accumulatedJson: string,
|
|
13
|
+
opts?: { force?: boolean },
|
|
14
|
+
) => void;
|
|
15
|
+
} {
|
|
16
|
+
const previewedToolUseIds = new Set<string>();
|
|
17
|
+
const lastInputEmitByToolUseId = new Map<
|
|
18
|
+
string,
|
|
19
|
+
{ emittedAt: number; accumulatedJson: string }
|
|
20
|
+
>();
|
|
21
|
+
const pendingInputEmitByToolUseId = new Map<
|
|
22
|
+
string,
|
|
23
|
+
{
|
|
24
|
+
timeout: ReturnType<typeof setTimeout>;
|
|
25
|
+
toolName: string;
|
|
26
|
+
accumulatedJson: string;
|
|
27
|
+
}
|
|
28
|
+
>();
|
|
29
|
+
|
|
30
|
+
const emitPreviewStart = (toolUseId: string, toolName: string): void => {
|
|
31
|
+
if (!onEvent || !toolUseId || !toolName) return;
|
|
32
|
+
if (previewedToolUseIds.has(toolUseId)) return;
|
|
33
|
+
previewedToolUseIds.add(toolUseId);
|
|
34
|
+
onEvent({ type: "tool_use_preview_start", toolUseId, toolName });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const emitInputJsonDelta = (
|
|
38
|
+
toolUseId: string,
|
|
39
|
+
toolName: string,
|
|
40
|
+
accumulatedJson: string,
|
|
41
|
+
opts?: { force?: boolean },
|
|
42
|
+
): void => {
|
|
43
|
+
if (!onEvent || !toolUseId || !toolName || !accumulatedJson) return;
|
|
44
|
+
emitPreviewStart(toolUseId, toolName);
|
|
45
|
+
|
|
46
|
+
const last = lastInputEmitByToolUseId.get(toolUseId);
|
|
47
|
+
if (last?.accumulatedJson === accumulatedJson) return;
|
|
48
|
+
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
if (
|
|
51
|
+
!opts?.force &&
|
|
52
|
+
last &&
|
|
53
|
+
now - last.emittedAt < INPUT_JSON_DELTA_EMIT_INTERVAL_MS
|
|
54
|
+
) {
|
|
55
|
+
const pending = pendingInputEmitByToolUseId.get(toolUseId);
|
|
56
|
+
if (pending) {
|
|
57
|
+
pending.toolName = toolName;
|
|
58
|
+
pending.accumulatedJson = accumulatedJson;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const delay = INPUT_JSON_DELTA_EMIT_INTERVAL_MS - (now - last.emittedAt);
|
|
62
|
+
const timeout = setTimeout(() => {
|
|
63
|
+
const latest = pendingInputEmitByToolUseId.get(toolUseId);
|
|
64
|
+
if (!latest) return;
|
|
65
|
+
pendingInputEmitByToolUseId.delete(toolUseId);
|
|
66
|
+
lastInputEmitByToolUseId.set(toolUseId, {
|
|
67
|
+
emittedAt: Date.now(),
|
|
68
|
+
accumulatedJson: latest.accumulatedJson,
|
|
69
|
+
});
|
|
70
|
+
onEvent({
|
|
71
|
+
type: "input_json_delta",
|
|
72
|
+
toolName: latest.toolName,
|
|
73
|
+
toolUseId,
|
|
74
|
+
accumulatedJson: latest.accumulatedJson,
|
|
75
|
+
});
|
|
76
|
+
}, delay);
|
|
77
|
+
timeout.unref?.();
|
|
78
|
+
pendingInputEmitByToolUseId.set(toolUseId, {
|
|
79
|
+
timeout,
|
|
80
|
+
toolName,
|
|
81
|
+
accumulatedJson,
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const pending = pendingInputEmitByToolUseId.get(toolUseId);
|
|
87
|
+
if (pending) {
|
|
88
|
+
clearTimeout(pending.timeout);
|
|
89
|
+
pendingInputEmitByToolUseId.delete(toolUseId);
|
|
90
|
+
}
|
|
91
|
+
lastInputEmitByToolUseId.set(toolUseId, {
|
|
92
|
+
emittedAt: now,
|
|
93
|
+
accumulatedJson,
|
|
94
|
+
});
|
|
95
|
+
onEvent({ type: "input_json_delta", toolName, toolUseId, accumulatedJson });
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return { emitPreviewStart, emitInputJsonDelta };
|
|
99
|
+
}
|
package/src/providers/types.ts
CHANGED
package/src/runtime/AGENTS.md
CHANGED
|
@@ -163,15 +163,16 @@ Verification SESSION state (pending sessions, codes, resend, rate-limit) is assi
|
|
|
163
163
|
|
|
164
164
|
The verified outcome is written in-process by the gateway: the HTTP guardian-attest handler calls `ContactStore.markChannelVerified` directly (verifiedVia "manual"), and the inbound code-match path (`gateway/src/verification/text-verification.ts`) writes via `upsertVerifiedContactChannel` / `createGuardianBinding` (verifiedVia "challenge"). The revoke/downgrade outcome is relayed from the daemon via `ipcCallPersistent("mark_channel_revoked", …)` to `ContactStore.markChannelRevoked`.
|
|
165
165
|
|
|
166
|
-
The `mark_channel_verified` IPC method exists as the daemon/CLI relay surface (symmetric with `mark_channel_revoked`) but has no caller: the trusted-contact CLI path sends codes only, and the outcome arrives via the inbound code-match path.
|
|
167
|
-
|
|
168
166
|
## Rate Limiting & Diagnostics
|
|
169
167
|
|
|
170
|
-
|
|
168
|
+
Most `/v1/*` endpoints share a per-client-IP sliding-window rate limiter (`middleware/rate-limiter.ts`):
|
|
171
169
|
|
|
172
|
-
- **Authenticated**:
|
|
170
|
+
- **Authenticated (loopback)**: 1200 requests/minute — desktop app, CLI, anything on the daemon's own host (`127.0.0.0/8`, `::1`). A cold sidebar load at thousands of conversations legitimately bursts far beyond the remote budget.
|
|
171
|
+
- **Authenticated (remote)**: 300 requests/minute — proxied non-loopback clients, keyed by the forwarded client IP.
|
|
173
172
|
- **Unauthenticated**: 20 requests/minute
|
|
174
173
|
|
|
174
|
+
**Exempt endpoints** (`isRateLimitExemptEndpoint`): the SSE stream (`events`) and liveness/readiness probes (`health`, `healthz`, `readyz`) bypass the per-minute limiter entirely. The stream is one long-lived connection, not a burst of requests, and 429-ing it drops the stream — which drives a client reconnect + full re-bootstrap loop that generates far more load than the limiter saves. Liveness probes must always answer or the client treats the assistant as down and reconnects harder. The events route still enforces auth downstream, and stream memory is bounded by SSE backpressure shedding + subscriber caps.
|
|
175
|
+
|
|
175
176
|
When the limit is exceeded, the limiter returns 429 and logs a structured warning (module: `rate-limiter`) with the denied endpoint and a breakdown of which endpoints consumed the budget in the current window. This makes it easy to identify whether the cause is rapid conversation switching, polling, or unexpected request volume.
|
|
176
177
|
|
|
177
178
|
Logs rotate daily into `$VELLUM_WORKSPACE_DIR/data/logs/assistant-YYYY-MM-DD.log` (or into the directory configured via `logFile.dir`). To watch rate limit events in real time:
|
|
@@ -87,6 +87,13 @@ interface WakeConversationProbe {
|
|
|
87
87
|
* persistent `setTrustContext`) and restores the prior value in its finally.
|
|
88
88
|
*/
|
|
89
89
|
turnTrustContextSets: Array<{ ctx: unknown; order: number }>;
|
|
90
|
+
/**
|
|
91
|
+
* `setTrustContext` writes to the persistent `conversation.trustContext`,
|
|
92
|
+
* in order. A trust-carrying wake's resolver leaves its trust here; the
|
|
93
|
+
* wake must put the prior value back so it doesn't linger for a later
|
|
94
|
+
* no-trust wake.
|
|
95
|
+
*/
|
|
96
|
+
trustContextSets: unknown[];
|
|
90
97
|
/**
|
|
91
98
|
* Every assignment to `conversation.wakePersonaOverride`, in order. A
|
|
92
99
|
* wake that applies an override records `[override, undefined]` — the
|
|
@@ -340,6 +347,10 @@ import type {
|
|
|
340
347
|
AgentLoopRunResult,
|
|
341
348
|
} from "../../agent/loop.js";
|
|
342
349
|
import type { Conversation } from "../../daemon/conversation.js";
|
|
350
|
+
import {
|
|
351
|
+
deleteConversation,
|
|
352
|
+
setConversation,
|
|
353
|
+
} from "../../daemon/conversation-registry.js";
|
|
343
354
|
import { ContextOverflowError, type Message } from "../../providers/types.js";
|
|
344
355
|
import {
|
|
345
356
|
__resetWakeChainForTests,
|
|
@@ -387,6 +398,8 @@ function makeWakeConversation(options: {
|
|
|
387
398
|
* (always under the mocked 200k window).
|
|
388
399
|
*/
|
|
389
400
|
estimatedInputTokens?: number;
|
|
401
|
+
/** Seed for the conversation's resting `trustContext`. */
|
|
402
|
+
initialTrustContext?: unknown;
|
|
390
403
|
}): WakeConversation {
|
|
391
404
|
const conversationId = options.conversationId ?? "conv-test";
|
|
392
405
|
const probe: WakeConversationProbe = {
|
|
@@ -401,6 +414,7 @@ function makeWakeConversation(options: {
|
|
|
401
414
|
processingDuringDrain: [],
|
|
402
415
|
allowedToolSnapshots: [],
|
|
403
416
|
turnTrustContextSets: [],
|
|
417
|
+
trustContextSets: [],
|
|
404
418
|
personaOverrideSets: [],
|
|
405
419
|
persistedAtEachEmit: [],
|
|
406
420
|
maybeCompactOrders: [],
|
|
@@ -413,6 +427,7 @@ function makeWakeConversation(options: {
|
|
|
413
427
|
let activeAllowedTools = options.initialAllowedTools;
|
|
414
428
|
let wakePersonaOverride: unknown;
|
|
415
429
|
let currentTurnTrustContext: unknown;
|
|
430
|
+
let persistentTrustContext: unknown = options.initialTrustContext;
|
|
416
431
|
const snapshotAllowedTools = (): string[] | undefined =>
|
|
417
432
|
activeAllowedTools ? [...activeAllowedTools].sort() : undefined;
|
|
418
433
|
|
|
@@ -526,7 +541,14 @@ function makeWakeConversation(options: {
|
|
|
526
541
|
},
|
|
527
542
|
getTurnChannelContext: () => null,
|
|
528
543
|
getTurnInterfaceContext: () => null,
|
|
529
|
-
trustContext
|
|
544
|
+
get trustContext() {
|
|
545
|
+
return persistentTrustContext;
|
|
546
|
+
},
|
|
547
|
+
// Mirrors Conversation.setTrustContext (coerces null → undefined).
|
|
548
|
+
setTrustContext(ctx: unknown) {
|
|
549
|
+
persistentTrustContext = ctx ?? undefined;
|
|
550
|
+
probe.trustContextSets.push(ctx);
|
|
551
|
+
},
|
|
530
552
|
buildCurrentSystemPrompt: () => "mock-system-prompt",
|
|
531
553
|
modelOverride: undefined,
|
|
532
554
|
...(drainQueue ? { drainQueue } : {}),
|
|
@@ -1535,6 +1557,141 @@ describe("wakeAgentForOpportunity", () => {
|
|
|
1535
1557
|
expect(conversation.currentTurnTrustContext).toBeUndefined();
|
|
1536
1558
|
});
|
|
1537
1559
|
|
|
1560
|
+
// ── Persistent-trust restore ────────────────────────────────────────
|
|
1561
|
+
// The resolver leaves the wake's trust on the conversation. The wake must
|
|
1562
|
+
// put the prior resting value back, or a later no-trust wake inherits it
|
|
1563
|
+
// through tool setup's `currentTurnTrustContext ?? trustContext` fallback.
|
|
1564
|
+
|
|
1565
|
+
const GUARDIAN_TRUST = {
|
|
1566
|
+
sourceChannel: "vellum",
|
|
1567
|
+
trustClass: "guardian",
|
|
1568
|
+
} as const;
|
|
1569
|
+
|
|
1570
|
+
// The wake reads the prior trust from the live registry, so a test that
|
|
1571
|
+
// wants to exercise the restore registers its double there and simulates
|
|
1572
|
+
// the resolver's write by setting the trust in resolveTarget.
|
|
1573
|
+
const withRegisteredConversation = async (
|
|
1574
|
+
conversation: WakeConversation,
|
|
1575
|
+
run: () => Promise<unknown>,
|
|
1576
|
+
): Promise<void> => {
|
|
1577
|
+
setConversation(conversation.conversationId, conversation as Conversation);
|
|
1578
|
+
try {
|
|
1579
|
+
await run();
|
|
1580
|
+
} finally {
|
|
1581
|
+
deleteConversation(conversation.conversationId);
|
|
1582
|
+
}
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
test("restores the conversation's prior trust once the wake ends", async () => {
|
|
1586
|
+
const priorTrust = {
|
|
1587
|
+
sourceChannel: "slack",
|
|
1588
|
+
trustClass: "trusted_contact",
|
|
1589
|
+
} as const;
|
|
1590
|
+
const conversation = makeWakeConversation({
|
|
1591
|
+
conversationId: "conv-trust-restore",
|
|
1592
|
+
initialTrustContext: priorTrust,
|
|
1593
|
+
});
|
|
1594
|
+
|
|
1595
|
+
await withRegisteredConversation(conversation, () =>
|
|
1596
|
+
wakeAgentForOpportunity(
|
|
1597
|
+
{
|
|
1598
|
+
conversationId: "conv-trust-restore",
|
|
1599
|
+
hint: "x",
|
|
1600
|
+
source: "t",
|
|
1601
|
+
trustContext: GUARDIAN_TRUST,
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
resolveTarget: async () => {
|
|
1605
|
+
conversation.setTrustContext(GUARDIAN_TRUST);
|
|
1606
|
+
return conversation;
|
|
1607
|
+
},
|
|
1608
|
+
},
|
|
1609
|
+
),
|
|
1610
|
+
);
|
|
1611
|
+
|
|
1612
|
+
// Resolver installs guardian, wake restores the prior value.
|
|
1613
|
+
expect(conversation.trustContextSets).toEqual([GUARDIAN_TRUST, priorTrust]);
|
|
1614
|
+
expect(conversation.trustContext).toEqual(priorTrust);
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
|
+
test("restores the prior trust even when the agent loop throws", async () => {
|
|
1618
|
+
const conversation = makeWakeConversation({
|
|
1619
|
+
conversationId: "conv-trust-restore-throw",
|
|
1620
|
+
runImpl: async () => {
|
|
1621
|
+
throw new Error("boom");
|
|
1622
|
+
},
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
await withRegisteredConversation(conversation, () =>
|
|
1626
|
+
wakeAgentForOpportunity(
|
|
1627
|
+
{
|
|
1628
|
+
conversationId: "conv-trust-restore-throw",
|
|
1629
|
+
hint: "x",
|
|
1630
|
+
source: "t",
|
|
1631
|
+
trustContext: GUARDIAN_TRUST,
|
|
1632
|
+
},
|
|
1633
|
+
{
|
|
1634
|
+
resolveTarget: async () => {
|
|
1635
|
+
conversation.setTrustContext(GUARDIAN_TRUST);
|
|
1636
|
+
return conversation;
|
|
1637
|
+
},
|
|
1638
|
+
},
|
|
1639
|
+
),
|
|
1640
|
+
);
|
|
1641
|
+
|
|
1642
|
+
// Nothing was resting before the wake, so it goes back to unset.
|
|
1643
|
+
expect(conversation.trustContext).toBeUndefined();
|
|
1644
|
+
});
|
|
1645
|
+
|
|
1646
|
+
test("leaves a trust that was re-set mid-run alone (identity guard)", async () => {
|
|
1647
|
+
const replaced = {
|
|
1648
|
+
sourceChannel: "vellum",
|
|
1649
|
+
trustClass: "unknown",
|
|
1650
|
+
} as const;
|
|
1651
|
+
const conversation = makeWakeConversation({
|
|
1652
|
+
conversationId: "conv-trust-guard",
|
|
1653
|
+
runImpl: async (input) => {
|
|
1654
|
+
conversation.setTrustContext(replaced);
|
|
1655
|
+
return runResult(input);
|
|
1656
|
+
},
|
|
1657
|
+
});
|
|
1658
|
+
|
|
1659
|
+
await withRegisteredConversation(conversation, () =>
|
|
1660
|
+
wakeAgentForOpportunity(
|
|
1661
|
+
{
|
|
1662
|
+
conversationId: "conv-trust-guard",
|
|
1663
|
+
hint: "x",
|
|
1664
|
+
source: "t",
|
|
1665
|
+
trustContext: GUARDIAN_TRUST,
|
|
1666
|
+
},
|
|
1667
|
+
{
|
|
1668
|
+
resolveTarget: async () => {
|
|
1669
|
+
conversation.setTrustContext(GUARDIAN_TRUST);
|
|
1670
|
+
return conversation;
|
|
1671
|
+
},
|
|
1672
|
+
},
|
|
1673
|
+
),
|
|
1674
|
+
);
|
|
1675
|
+
|
|
1676
|
+
// The wake sees a different reference than it installed, so it doesn't
|
|
1677
|
+
// restore: two writes (resolver install, mid-run replacement), no third.
|
|
1678
|
+
expect(conversation.trustContext).toEqual(replaced);
|
|
1679
|
+
expect(conversation.trustContextSets).toHaveLength(2);
|
|
1680
|
+
});
|
|
1681
|
+
|
|
1682
|
+
test("never touches the persistent trust when the wake carries none", async () => {
|
|
1683
|
+
const conversation = makeWakeConversation({
|
|
1684
|
+
conversationId: "conv-trust-none",
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
await wakeAgentForOpportunity(
|
|
1688
|
+
{ conversationId: "conv-trust-none", hint: "x", source: "t" },
|
|
1689
|
+
{ resolveTarget: async () => conversation },
|
|
1690
|
+
);
|
|
1691
|
+
|
|
1692
|
+
expect(conversation.trustContextSets).toHaveLength(0);
|
|
1693
|
+
});
|
|
1694
|
+
|
|
1538
1695
|
test("two concurrent wakes on the same conversation are serialized", async () => {
|
|
1539
1696
|
// Build a target whose agentLoop.run resolves only when we signal.
|
|
1540
1697
|
const gate1 = Promise.withResolvers<void>();
|
|
@@ -73,7 +73,7 @@ describe("getGuardianBinding", () => {
|
|
|
73
73
|
expect(binding?.verifiedVia).toBe("verified");
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
test("
|
|
76
|
+
test("a missing principal surfaces as null (unresolved), never an empty string", async () => {
|
|
77
77
|
mockGuardianList = [
|
|
78
78
|
{
|
|
79
79
|
channelType: "telegram",
|
|
@@ -85,7 +85,7 @@ describe("getGuardianBinding", () => {
|
|
|
85
85
|
|
|
86
86
|
const binding = await getGuardianBinding("asst-1", "telegram");
|
|
87
87
|
|
|
88
|
-
expect(binding?.guardianPrincipalId).
|
|
88
|
+
expect(binding?.guardianPrincipalId).toBeNull();
|
|
89
89
|
expect(binding?.guardianDeliveryChatId).toBe("");
|
|
90
90
|
expect(binding?.verifiedAt).toBe(0);
|
|
91
91
|
});
|