@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
|
@@ -1354,6 +1354,113 @@ export function cleanupStandaloneSurface(
|
|
|
1354
1354
|
}
|
|
1355
1355
|
}
|
|
1356
1356
|
|
|
1357
|
+
/**
|
|
1358
|
+
* How long to wait for a client to acknowledge an `open_panel` command
|
|
1359
|
+
* before reporting failure to the model. The ack round-trip is one SSE
|
|
1360
|
+
* delivery plus one HTTP POST, so this is generous — it only elapses when
|
|
1361
|
+
* no connected client rendered the panel (event dropped, no client
|
|
1362
|
+
* listening, or a client build that predates panel acknowledgment).
|
|
1363
|
+
*/
|
|
1364
|
+
const OPEN_PANEL_ACK_TIMEOUT_MS = 10_000;
|
|
1365
|
+
|
|
1366
|
+
/**
|
|
1367
|
+
* Open the channel-setup drawer on a connected client and wait for the
|
|
1368
|
+
* client's acknowledgment.
|
|
1369
|
+
*
|
|
1370
|
+
* `open_panel` is a side-effect-only command: it is never persisted to the
|
|
1371
|
+
* transcript, so a dropped event is unrecoverable by reload. The ack is what
|
|
1372
|
+
* makes the emitting tool result truthful — "displayed" must mean a client
|
|
1373
|
+
* actually rendered the drawer, not merely that the event was emitted.
|
|
1374
|
+
*
|
|
1375
|
+
* Reuses the standalone-surface pending machinery: the client responds via
|
|
1376
|
+
* the existing surface-action route (`actionId: "ack"` on success, `"nack"`
|
|
1377
|
+
* with `data.reason` when it received the event but could not open the
|
|
1378
|
+
* panel), which `handleSurfaceAction` intercepts and resolves without an
|
|
1379
|
+
* LLM turn. The surface-state entry exists only so the surface-action route
|
|
1380
|
+
* can resolve the owning conversation by `surfaceId`; `cleanupStandaloneSurface`
|
|
1381
|
+
* removes it on every outcome.
|
|
1382
|
+
*/
|
|
1383
|
+
export function openChannelSetupPanel(
|
|
1384
|
+
ctx: SurfaceConversationContext,
|
|
1385
|
+
surfaceId: string,
|
|
1386
|
+
data: Record<string, unknown>,
|
|
1387
|
+
options?: { signal?: AbortSignal; timeoutMs?: number },
|
|
1388
|
+
): Promise<InteractiveUiResult> {
|
|
1389
|
+
if (!canShowInteractiveUi(ctx) || !ctx.pendingStandaloneSurfaces) {
|
|
1390
|
+
log.warn(
|
|
1391
|
+
{
|
|
1392
|
+
conversationId: ctx.conversationId,
|
|
1393
|
+
hasNoClient: ctx.hasNoClient,
|
|
1394
|
+
channel: ctx.channelCapabilities?.channel,
|
|
1395
|
+
},
|
|
1396
|
+
"channel_setup panel: no interactive UI capability; failing closed",
|
|
1397
|
+
);
|
|
1398
|
+
return Promise.resolve({
|
|
1399
|
+
status: "cancelled" as const,
|
|
1400
|
+
surfaceId,
|
|
1401
|
+
cancellationReason: "no_interactive_surface" as const,
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
const pendingMap = ctx.pendingStandaloneSurfaces;
|
|
1405
|
+
const signal = options?.signal;
|
|
1406
|
+
const timeoutMs = options?.timeoutMs ?? OPEN_PANEL_ACK_TIMEOUT_MS;
|
|
1407
|
+
|
|
1408
|
+
if (signal?.aborted) {
|
|
1409
|
+
return Promise.resolve({
|
|
1410
|
+
status: "cancelled" as const,
|
|
1411
|
+
surfaceId,
|
|
1412
|
+
cancellationReason: "resolver_unavailable" as const,
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
return new Promise<InteractiveUiResult>((resolve) => {
|
|
1417
|
+
const settle = (result: InteractiveUiResult) => {
|
|
1418
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1419
|
+
resolve(result);
|
|
1420
|
+
};
|
|
1421
|
+
|
|
1422
|
+
const timer = setTimeout(() => {
|
|
1423
|
+
cleanupStandaloneSurface(ctx, surfaceId);
|
|
1424
|
+
log.warn(
|
|
1425
|
+
{ conversationId: ctx.conversationId, surfaceId, timeoutMs },
|
|
1426
|
+
"channel_setup panel: no client acknowledged open_panel",
|
|
1427
|
+
);
|
|
1428
|
+
settle({ status: "timed_out", surfaceId });
|
|
1429
|
+
}, timeoutMs);
|
|
1430
|
+
|
|
1431
|
+
const onAbort = () => {
|
|
1432
|
+
cleanupStandaloneSurface(ctx, surfaceId);
|
|
1433
|
+
settle({
|
|
1434
|
+
status: "cancelled",
|
|
1435
|
+
surfaceId,
|
|
1436
|
+
cancellationReason: "resolver_unavailable",
|
|
1437
|
+
});
|
|
1438
|
+
};
|
|
1439
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1440
|
+
|
|
1441
|
+
pendingMap.set(surfaceId, {
|
|
1442
|
+
resolve: settle,
|
|
1443
|
+
timer,
|
|
1444
|
+
surfaceType: "channel_setup",
|
|
1445
|
+
});
|
|
1446
|
+
// Registered so the surface-action route's by-surfaceId conversation
|
|
1447
|
+
// lookup finds this conversation when the ack arrives without a
|
|
1448
|
+
// conversationId. Cleared by cleanupStandaloneSurface on all outcomes.
|
|
1449
|
+
ctx.surfaceState.set(surfaceId, {
|
|
1450
|
+
surfaceType: "channel_setup",
|
|
1451
|
+
data: data as SurfaceData,
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
ctx.sendToClient({
|
|
1455
|
+
type: "open_panel",
|
|
1456
|
+
panelType: "channel_setup",
|
|
1457
|
+
data,
|
|
1458
|
+
conversationId: ctx.conversationId,
|
|
1459
|
+
surfaceId,
|
|
1460
|
+
});
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1357
1464
|
/**
|
|
1358
1465
|
* Handle content_changed action from document editor.
|
|
1359
1466
|
* Auto-saves the document content to the app store.
|
|
@@ -1787,6 +1894,20 @@ export async function handleSurfaceAction(
|
|
|
1787
1894
|
summary,
|
|
1788
1895
|
};
|
|
1789
1896
|
|
|
1897
|
+
// channel_setup pendings are protocol-level acknowledgments for the
|
|
1898
|
+
// `open_panel` command, not user-facing surfaces: nothing was rendered
|
|
1899
|
+
// in the transcript, so there is no completion to broadcast, persist,
|
|
1900
|
+
// or count as an activation commit. Resolve and clean up only.
|
|
1901
|
+
if (standalone.surfaceType === "channel_setup") {
|
|
1902
|
+
cleanupStandaloneSurface(ctx, surfaceId);
|
|
1903
|
+
standalone.resolve(result);
|
|
1904
|
+
log.info(
|
|
1905
|
+
{ conversationId: ctx.conversationId, surfaceId, actionId, status },
|
|
1906
|
+
"open_panel acknowledgment resolved",
|
|
1907
|
+
);
|
|
1908
|
+
return { accepted: true, conversationId: ctx.conversationId };
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1790
1911
|
broadcastMessage({
|
|
1791
1912
|
type: "ui_surface_complete",
|
|
1792
1913
|
conversationId: ctx.conversationId,
|
|
@@ -2925,6 +3046,56 @@ export async function surfaceProxyResolver(
|
|
|
2925
3046
|
const surfaceType = input.surface_type as SurfaceType;
|
|
2926
3047
|
const title = typeof input.title === "string" ? input.title : undefined;
|
|
2927
3048
|
const rawData = isPlainObject(input.data) ? input.data : {};
|
|
3049
|
+
|
|
3050
|
+
// channel_setup is a side-effect-only command: it opens the channel setup
|
|
3051
|
+
// drawer on the client. Emitted as `open_panel` (not `ui_surface_show`)
|
|
3052
|
+
// so the rolling-snapshot reducer never folds it into the transcript.
|
|
3053
|
+
// Because the event is never persisted, success is gated on a client
|
|
3054
|
+
// acknowledgment — "displayed" must mean a client actually rendered the
|
|
3055
|
+
// drawer, otherwise the model announces a panel the user cannot see.
|
|
3056
|
+
if (surfaceType === "channel_setup") {
|
|
3057
|
+
const ack = await openChannelSetupPanel(
|
|
3058
|
+
ctx,
|
|
3059
|
+
surfaceId,
|
|
3060
|
+
rawData as Record<string, unknown>,
|
|
3061
|
+
{ signal },
|
|
3062
|
+
);
|
|
3063
|
+
|
|
3064
|
+
if (ack.status === "submitted" && ack.actionId === "ack") {
|
|
3065
|
+
return {
|
|
3066
|
+
content: JSON.stringify({ surfaceId, status: "displayed" }),
|
|
3067
|
+
isError: false,
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
if (ack.status === "submitted") {
|
|
3072
|
+
// Client received the event but could not open the panel (nack).
|
|
3073
|
+
const reason =
|
|
3074
|
+
typeof ack.submittedData?.reason === "string"
|
|
3075
|
+
? ack.submittedData.reason
|
|
3076
|
+
: "unknown";
|
|
3077
|
+
return {
|
|
3078
|
+
content: `The channel setup panel could not be opened by the connected client (reason: ${reason}). Do NOT tell the user the panel is open. Troubleshoot with the user (e.g. ask them to reopen or refresh the Vellum app), then retry ui_show.`,
|
|
3079
|
+
isError: true,
|
|
3080
|
+
};
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
if (ack.status === "timed_out") {
|
|
3084
|
+
return {
|
|
3085
|
+
content:
|
|
3086
|
+
"No connected client confirmed opening the channel setup panel. Do NOT tell the user the panel is open. The user's app may be closed, viewing a different conversation, or running a version that cannot show this panel. Ask the user to open this conversation in the Vellum app (web or desktop), then retry ui_show.",
|
|
3087
|
+
isError: true,
|
|
3088
|
+
};
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
// cancelled — no interactive client, or the turn was aborted.
|
|
3092
|
+
return {
|
|
3093
|
+
content:
|
|
3094
|
+
"The channel setup panel could not be opened — no connected client can render interactive UI. Do NOT tell the user the panel is open. Ask the user to open the Vellum app (web or desktop), then retry ui_show.",
|
|
3095
|
+
isError: true,
|
|
3096
|
+
};
|
|
3097
|
+
}
|
|
3098
|
+
|
|
2928
3099
|
// Each surface type that has a canonical Zod schema gets parsed through it;
|
|
2929
3100
|
// the rest pass through raw until migrated (LUM-2134 scope). The per-type
|
|
2930
3101
|
// normalizers validate+recover; the union cast at the end is only for the
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { afterEach, describe, expect, test } from "bun:test";
|
|
4
|
+
|
|
5
|
+
import { getAllDefaultPlugins } from "../plugins/defaults/index.js";
|
|
6
|
+
import { getWorkspacePluginsDir } from "../util/platform.js";
|
|
7
|
+
import { getEffectiveEnabledPluginSet } from "./conversation-tool-setup.js";
|
|
8
|
+
|
|
9
|
+
const DEFAULT_NAMES = getAllDefaultPlugins().map((p) => p.manifest.name);
|
|
10
|
+
|
|
11
|
+
/** Write a `.disabled` sentinel for `pluginName`; returns the created dir. */
|
|
12
|
+
function disablePlugin(pluginName: string): string {
|
|
13
|
+
const dir = join(getWorkspacePluginsDir(), pluginName);
|
|
14
|
+
mkdirSync(dir, { recursive: true });
|
|
15
|
+
writeFileSync(join(dir, ".disabled"), "");
|
|
16
|
+
return dir;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("getEffectiveEnabledPluginSet", () => {
|
|
20
|
+
test("returns null when enabledPlugins is null (no per-chat restriction)", () => {
|
|
21
|
+
expect(getEffectiveEnabledPluginSet({ enabledPlugins: null })).toBeNull();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("returns null when enabledPlugins is undefined", () => {
|
|
25
|
+
expect(getEffectiveEnabledPluginSet({})).toBeNull();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("unions first-party defaults with the selected user plugins", () => {
|
|
29
|
+
const set = getEffectiveEnabledPluginSet({ enabledPlugins: ["user-a"] });
|
|
30
|
+
expect(set).not.toBeNull();
|
|
31
|
+
// The explicitly selected user plugin is present...
|
|
32
|
+
expect(set?.has("user-a")).toBe(true);
|
|
33
|
+
// ...alongside core default-plugin infrastructure, which the new-chat pills
|
|
34
|
+
// never list and so must never be filtered out.
|
|
35
|
+
expect(set?.has("default-memory")).toBe(true);
|
|
36
|
+
expect(set?.has("default-turn-context")).toBe(true);
|
|
37
|
+
expect(set?.has("default-workspace")).toBe(true);
|
|
38
|
+
expect(set?.has("default-session")).toBe(true);
|
|
39
|
+
expect(set?.has("default-title-generate")).toBe(true);
|
|
40
|
+
for (const name of DEFAULT_NAMES) {
|
|
41
|
+
expect(set?.has(name)).toBe(true);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("still excludes a non-selected user plugin", () => {
|
|
46
|
+
const set = getEffectiveEnabledPluginSet({ enabledPlugins: ["user-a"] });
|
|
47
|
+
expect(set?.has("user-b")).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("an explicit empty scope still includes the defaults", () => {
|
|
51
|
+
const set = getEffectiveEnabledPluginSet({ enabledPlugins: [] });
|
|
52
|
+
expect(set).not.toBeNull();
|
|
53
|
+
expect(set?.has("default-memory")).toBe(true);
|
|
54
|
+
expect(set?.size).toBe(DEFAULT_NAMES.length);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("workspace-disabled plugins (precedence)", () => {
|
|
58
|
+
const created: string[] = [];
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
for (const dir of created.splice(0)) {
|
|
61
|
+
rmSync(dir, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("drops a workspace-disabled default the conversation did not select", () => {
|
|
66
|
+
created.push(disablePlugin("default-memory"));
|
|
67
|
+
const set = getEffectiveEnabledPluginSet({ enabledPlugins: ["user-a"] });
|
|
68
|
+
expect(set?.has("user-a")).toBe(true);
|
|
69
|
+
// The workspace-disabled default is excluded (rule 2 beats rule 3)...
|
|
70
|
+
expect(set?.has("default-memory")).toBe(false);
|
|
71
|
+
// ...while the other defaults remain.
|
|
72
|
+
expect(set?.has("default-turn-context")).toBe(true);
|
|
73
|
+
expect(set?.size).toBe(DEFAULT_NAMES.length); // user-a + defaults - memory
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("keeps a conversation-enabled plugin even if workspace-disabled", () => {
|
|
77
|
+
// Rule 1 (per-conversation explicit enable) beats rule 2 (workspace).
|
|
78
|
+
created.push(disablePlugin("user-a"));
|
|
79
|
+
const set = getEffectiveEnabledPluginSet({
|
|
80
|
+
enabledPlugins: ["user-a", "user-b"],
|
|
81
|
+
});
|
|
82
|
+
expect(set?.has("user-a")).toBe(true);
|
|
83
|
+
expect(set?.has("user-b")).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("keeps a default the conversation explicitly enabled even if workspace-disabled", () => {
|
|
87
|
+
// Rule 1 beats rule 2 for defaults too.
|
|
88
|
+
created.push(disablePlugin("default-memory"));
|
|
89
|
+
const set = getEffectiveEnabledPluginSet({
|
|
90
|
+
enabledPlugins: ["default-memory"],
|
|
91
|
+
});
|
|
92
|
+
expect(set?.has("default-memory")).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -17,6 +17,8 @@ import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
|
17
17
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
18
18
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
19
19
|
import { getBindingByConversation } from "../persistence/external-conversation-store.js";
|
|
20
|
+
import { DEFAULT_PLUGIN_NAMES } from "../plugins/defaults/default-plugin-names.js";
|
|
21
|
+
import { isPluginDisabled } from "../plugins/disabled-state.js";
|
|
20
22
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
21
23
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
22
24
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
@@ -25,6 +27,7 @@ import {
|
|
|
25
27
|
getMcpToolDefinitions,
|
|
26
28
|
getPluginToolDefinitions,
|
|
27
29
|
getTool,
|
|
30
|
+
getToolOwner,
|
|
28
31
|
getWorkspaceToolDefinitions,
|
|
29
32
|
getWorkspaceToolNames,
|
|
30
33
|
} from "../tools/registry.js";
|
|
@@ -119,6 +122,50 @@ export function resolveConversationAttribution(
|
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Resolve a conversation's effective per-chat plugin scope as a Set for
|
|
127
|
+
* membership checks. Returns `null` when there is no per-chat restriction
|
|
128
|
+
* (`enabledPlugins` null/undefined) — meaning all globally-enabled plugins
|
|
129
|
+
* apply — otherwise a Set of the scoped plugin ids. Later tool/skill/hook
|
|
130
|
+
* filters intersect their candidate set against this; `null` is the no-op
|
|
131
|
+
* sentinel (no intersection).
|
|
132
|
+
*
|
|
133
|
+
* Enablement precedence, highest first:
|
|
134
|
+
* 1. Explicit per-conversation enable/disable — the `enabledPlugins`
|
|
135
|
+
* allowlist. A plugin listed here is enabled for this chat even if it is
|
|
136
|
+
* disabled at the workspace level; an installed plugin omitted from a
|
|
137
|
+
* non-null list is disabled for this chat.
|
|
138
|
+
* 2. Explicit workspace enable/disable — the `.disabled` sentinel
|
|
139
|
+
* (`assistant plugins disable <name>`), via {@link isPluginDisabled}.
|
|
140
|
+
* 3. Default plugins are enabled by default.
|
|
141
|
+
*
|
|
142
|
+
* The first-party default plugins are therefore unioned into a non-null scope
|
|
143
|
+
* unless they are disabled at the workspace level: they are core runtime
|
|
144
|
+
* infrastructure (memory, turn-context, workspace grounding, session framing,
|
|
145
|
+
* history repair, title generation, …), not user-toggleable extensions, and
|
|
146
|
+
* the per-chat pills only list user-INSTALLED plugins (`/v1/plugins`), so
|
|
147
|
+
* without this union deselecting any pill would intersect the defaults out and
|
|
148
|
+
* silently disable core behavior. A workspace-disabled default is left out so
|
|
149
|
+
* `assistant plugins disable default-*` still takes effect; a default the
|
|
150
|
+
* conversation explicitly enabled (rule 1) stays in regardless. Unioning here
|
|
151
|
+
* fixes every consumer (tools/skills/injectors/hooks) at the single chokepoint.
|
|
152
|
+
*/
|
|
153
|
+
export function getEffectiveEnabledPluginSet(conv: {
|
|
154
|
+
enabledPlugins?: string[] | null;
|
|
155
|
+
}): Set<string> | null {
|
|
156
|
+
if (conv.enabledPlugins == null) return null;
|
|
157
|
+
// Rule 1: the conversation's explicit selections always apply.
|
|
158
|
+
const effective = new Set(conv.enabledPlugins);
|
|
159
|
+
// Rules 2 + 3: add a default the conversation did not already decide, unless
|
|
160
|
+
// it is disabled at the workspace level.
|
|
161
|
+
for (const name of DEFAULT_PLUGIN_NAMES) {
|
|
162
|
+
if (!effective.has(name) && !isPluginDisabled(name)) {
|
|
163
|
+
effective.add(name);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return effective;
|
|
167
|
+
}
|
|
168
|
+
|
|
122
169
|
// ── createToolExecutor ───────────────────────────────────────────────
|
|
123
170
|
|
|
124
171
|
/**
|
|
@@ -161,6 +208,27 @@ export function createToolExecutor(
|
|
|
161
208
|
};
|
|
162
209
|
};
|
|
163
210
|
|
|
211
|
+
// Per-chat plugin scope guard for the `skill_execute` dispatch path. The
|
|
212
|
+
// wire definitions + per-turn `allowedToolNames` already keep an excluded
|
|
213
|
+
// plugin's tools off the model's tool surface, but `skill_execute` names its
|
|
214
|
+
// inner tool by string, so resolve the inner tool's owner and reject when it
|
|
215
|
+
// belongs to a plugin outside the conversation's effective set. Authoritative
|
|
216
|
+
// regardless of how the name was obtained (also covers name collisions where
|
|
217
|
+
// the projected name is owned by a different, in-scope source). `null` =
|
|
218
|
+
// no per-chat restriction; non-plugin tools are never blocked.
|
|
219
|
+
const rejectOutOfScopePluginTool = (
|
|
220
|
+
toolName: string,
|
|
221
|
+
effectiveSet: Set<string> | null,
|
|
222
|
+
): ToolExecutionResult | null => {
|
|
223
|
+
if (effectiveSet === null) return null;
|
|
224
|
+
const owner = getToolOwner(toolName);
|
|
225
|
+
if (owner?.kind !== "plugin" || effectiveSet.has(owner.id)) return null;
|
|
226
|
+
return {
|
|
227
|
+
content: `Tool "${toolName}" belongs to a plugin that is not enabled in this conversation.`,
|
|
228
|
+
isError: true,
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
|
|
164
232
|
return async (
|
|
165
233
|
name: string,
|
|
166
234
|
input: Record<string, unknown>,
|
|
@@ -170,6 +238,11 @@ export function createToolExecutor(
|
|
|
170
238
|
const { name: executionName, input: executionInput } =
|
|
171
239
|
resolveToolInvocationAlias(name, input, ctx.allowedToolNames);
|
|
172
240
|
|
|
241
|
+
// Resolve the conversation's effective per-chat plugin scope once per tool
|
|
242
|
+
// call: reused for the ToolContext field (read by skill-surface tools) and
|
|
243
|
+
// the skill_execute dispatch guard below.
|
|
244
|
+
const effectiveEnabledPluginSet = getEffectiveEnabledPluginSet(ctx);
|
|
245
|
+
|
|
173
246
|
// The execution-layer gate must run FIRST — before any interception or
|
|
174
247
|
// pre-execution side effect (DoorDash step marking) — so a non-allowlisted
|
|
175
248
|
// tool can neither run nor mutate conversation state. `skill_execute` is
|
|
@@ -225,6 +298,7 @@ export function createToolExecutor(
|
|
|
225
298
|
overrideProfile: ctx.currentTurnOverrideProfile,
|
|
226
299
|
invokingCallSite: ctx.currentCallSite ?? "mainAgent",
|
|
227
300
|
attribution: resolveConversationAttribution(ctx),
|
|
301
|
+
enabledPluginSet: effectiveEnabledPluginSet,
|
|
228
302
|
onToolLifecycleEvent: handleToolLifecycleEvent,
|
|
229
303
|
sendToClient: (msg) => {
|
|
230
304
|
// Tool context's sendToClient uses a loose { type: string; [key: string]: unknown }
|
|
@@ -313,6 +387,14 @@ export function createToolExecutor(
|
|
|
313
387
|
const innerRejection = rejectNonAllowlistedTool(toolName);
|
|
314
388
|
if (innerRejection) return innerRejection;
|
|
315
389
|
|
|
390
|
+
// Per-chat plugin scope: reject the resolved inner tool when it belongs
|
|
391
|
+
// to a plugin outside the conversation's effective set.
|
|
392
|
+
const pluginRejection = rejectOutOfScopePluginTool(
|
|
393
|
+
toolName,
|
|
394
|
+
effectiveEnabledPluginSet,
|
|
395
|
+
);
|
|
396
|
+
if (pluginRejection) return pluginRejection;
|
|
397
|
+
|
|
316
398
|
const rawResult = await executor.execute(
|
|
317
399
|
toolName,
|
|
318
400
|
toolInput,
|
|
@@ -426,6 +508,15 @@ export interface SkillProjectionContext {
|
|
|
426
508
|
readonly transportInterface?: InterfaceId;
|
|
427
509
|
/** Per-turn override profile. */
|
|
428
510
|
currentTurnOverrideProfile?: string;
|
|
511
|
+
/**
|
|
512
|
+
* The conversation's per-chat plugin scope (mirrors
|
|
513
|
+
* {@link Conversation.enabledPlugins}). `null`/absent means no per-chat
|
|
514
|
+
* restriction; otherwise plugin-owned tools and skills are intersected with
|
|
515
|
+
* the effective set (the scope unioned with the always-on first-party
|
|
516
|
+
* defaults) via {@link getEffectiveEnabledPluginSet}. Read per turn so a
|
|
517
|
+
* mid-conversation scope change is picked up.
|
|
518
|
+
*/
|
|
519
|
+
readonly enabledPlugins?: string[] | null;
|
|
429
520
|
/**
|
|
430
521
|
* Conversation id for `skill_loaded` telemetry. Absent (e.g. minimal test
|
|
431
522
|
* contexts) disables telemetry recording in the skill projection.
|
|
@@ -703,6 +794,12 @@ export function createResolveToolsCallback(
|
|
|
703
794
|
return [];
|
|
704
795
|
}
|
|
705
796
|
|
|
797
|
+
// Resolve the conversation's effective per-chat plugin scope ONCE for this
|
|
798
|
+
// turn and reuse it for the plugin-tool filter and the skill projection.
|
|
799
|
+
// `null` = no per-chat restriction; otherwise a fresh Set of the selection
|
|
800
|
+
// unioned with the always-on first-party defaults.
|
|
801
|
+
const effectiveEnabledPluginSet = getEffectiveEnabledPluginSet(ctx);
|
|
802
|
+
|
|
706
803
|
// Reconcile workspace tool overrides under `<workspaceDir>/tools/` into
|
|
707
804
|
// the registry, then re-read them below — the on-read replacement for a
|
|
708
805
|
// filesystem watcher. Fire-and-forget: the reconcile is idempotent,
|
|
@@ -717,10 +814,25 @@ export function createResolveToolsCallback(
|
|
|
717
814
|
// so combine them with the core snapshot before filtering.
|
|
718
815
|
const currentPluginDefs = getPluginToolDefinitions();
|
|
719
816
|
|
|
817
|
+
// Scope plugin tools to the conversation's per-chat plugin set. `null`
|
|
818
|
+
// leaves the list unchanged (no per-chat restriction); otherwise keep only
|
|
819
|
+
// tools whose owning plugin id is in the set, mirroring the
|
|
820
|
+
// `subagentAllowedTools` intersection below. Ownership lives in the registry
|
|
821
|
+
// (queried via getToolOwner), not on the Tool object.
|
|
822
|
+
const scopedPluginDefs =
|
|
823
|
+
effectiveEnabledPluginSet === null
|
|
824
|
+
? currentPluginDefs
|
|
825
|
+
: currentPluginDefs.filter((d) => {
|
|
826
|
+
const ownerId = getToolOwner(d.name)?.id;
|
|
827
|
+
return (
|
|
828
|
+
ownerId !== undefined && effectiveEnabledPluginSet.has(ownerId)
|
|
829
|
+
);
|
|
830
|
+
});
|
|
831
|
+
|
|
720
832
|
// Filter core + plugin tools based on current conversation context so that
|
|
721
833
|
// tools irrelevant to this turn (e.g. UI tools when no client is connected)
|
|
722
834
|
// are omitted from the definitions sent to the provider.
|
|
723
|
-
const filteredCoreDefs = [...coreToolDefs, ...
|
|
835
|
+
const filteredCoreDefs = [...coreToolDefs, ...scopedPluginDefs].filter(
|
|
724
836
|
(d) => isToolActiveForContext(d.name, ctx),
|
|
725
837
|
);
|
|
726
838
|
|
|
@@ -774,6 +886,9 @@ export function createResolveToolsCallback(
|
|
|
774
886
|
preactivatedSkillIds: effectivePreactivated,
|
|
775
887
|
previouslyActiveSkillIds: ctx.skillProjectionState,
|
|
776
888
|
cache: ctx.skillProjectionCache,
|
|
889
|
+
// Scope plugin-contributed skills to the conversation's per-chat plugin
|
|
890
|
+
// selection (null = no restriction).
|
|
891
|
+
effectiveEnabledPluginSet,
|
|
777
892
|
// skill_loaded telemetry context — resolved per turn so attribution
|
|
778
893
|
// reflects the call site/profile the current turn actually runs on.
|
|
779
894
|
telemetry:
|