@vellumai/assistant 0.10.2 → 0.10.3-dev.202606252046.9075fd5
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/bun.lock +20 -0
- package/docs/workspace-tools.md +42 -33
- package/eslint-rules/cli-no-daemon-internals.js +6 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +31 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +44 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +14 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +17 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +28 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +41 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/openapi.yaml +196 -56
- package/package.json +4 -1
- package/scripts/test.sh +36 -15
- package/src/__tests__/actor-token-service.test.ts +36 -14
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +83 -31
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +2 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/approval-cascade.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +42 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -0
- package/src/__tests__/btw-routes.test.ts +2 -0
- package/src/__tests__/build-persisted-content.test.ts +2 -0
- package/src/__tests__/call-controller.test.ts +19 -0
- package/src/__tests__/channel-approval-routes.test.ts +21 -26
- package/src/__tests__/channel-delivery-store.test.ts +28 -0
- package/src/__tests__/channel-guardian.test.ts +164 -78
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +11 -19
- package/src/__tests__/channel-reply-delivery.test.ts +2 -0
- package/src/__tests__/code-search-tool.test.ts +585 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-ledger-store.test.ts +128 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +2 -0
- package/src/__tests__/compactor-low-watermark-cut.test.ts +2 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +2 -0
- package/src/__tests__/compactor-summary-call-truncation.test.ts +2 -0
- package/src/__tests__/compactor-web-search-strip.test.ts +2 -0
- package/src/__tests__/config-loader-backfill.test.ts +123 -10
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +31 -29
- package/src/__tests__/consult-deadline.test.ts +60 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +156 -0
- package/src/__tests__/contact-store-user-file.test.ts +7 -10
- package/src/__tests__/contacts-relay-reads.test.ts +19 -24
- package/src/__tests__/contacts-write.test.ts +0 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +134 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +9 -11
- package/src/__tests__/conversation-confirmation-signals.test.ts +2 -0
- package/src/__tests__/conversation-fork-crud.test.ts +354 -24
- package/src/__tests__/conversation-history-web-search.test.ts +2 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -0
- package/src/__tests__/conversation-load-history-stripped.test.ts +2 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-process-callsite.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +91 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +14 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +14 -0
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +2 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +29 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-compaction-events-migration.test.ts +129 -0
- package/src/__tests__/db-migration-rollback.test.ts +205 -171
- package/src/__tests__/db-test-helpers.ts +5 -4
- package/src/__tests__/delete-propagation.test.ts +5 -3
- package/src/__tests__/deterministic-verification-control-plane.test.ts +4 -2
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/dm-backfill.test.ts +6 -4
- package/src/__tests__/dm-persistence.test.ts +2 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +7 -6
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/exploration-drift-hook.test.ts +3 -2
- package/src/__tests__/filing-service.test.ts +2 -0
- package/src/__tests__/guardian-binding-drift-heal.test.ts +104 -19
- package/src/__tests__/guardian-dispatch.test.ts +140 -1
- package/src/__tests__/guardian-expiry-notifier.test.ts +282 -0
- package/src/__tests__/guardian-outbound-http.test.ts +13 -0
- package/src/__tests__/guardian-routing-state.test.ts +6 -10
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +46 -19
- package/src/__tests__/helpers/create-guardian-binding.ts +15 -23
- package/src/__tests__/helpers/mock-logger.ts +1 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +96 -0
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-user-message-parity.test.ts +290 -8
- package/src/__tests__/inbound-invite-redemption.test.ts +115 -10
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/invite-redemption-service.test.ts +471 -53
- package/src/__tests__/invite-routes-http.test.ts +34 -0
- package/src/__tests__/invite-service-ipc.test.ts +65 -2
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +71 -9
- package/src/__tests__/llm-usage-store.test.ts +25 -0
- package/src/__tests__/mcp-config-secret-boundary.test.ts +392 -0
- package/src/__tests__/mcp-health-check.test.ts +2 -1
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +2 -0
- package/src/__tests__/messaging-send-tool.test.ts +2 -0
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +275 -5
- package/src/__tests__/native-web-search.test.ts +2 -0
- package/src/__tests__/non-member-access-request.test.ts +191 -17
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +6 -0
- package/src/__tests__/notification-guardian-path.test.ts +19 -0
- package/src/__tests__/onboarding-persona-write.test.ts +52 -22
- package/src/__tests__/openai-provider.test.ts +22 -12
- package/src/__tests__/openai-responses-provider.test.ts +12 -2
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persist-onboarding-artifacts.test.ts +1 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/persona-resolver.test.ts +75 -45
- package/src/__tests__/plugin-bootstrap.test.ts +21 -83
- package/src/__tests__/plugin-disabled-state.test.ts +190 -0
- package/src/__tests__/plugin-pipeline.test.ts +96 -0
- package/src/__tests__/plugin-route-contribution.test.ts +6 -19
- package/src/__tests__/plugin-tool-contribution.test.ts +5 -20
- package/src/__tests__/plugin-types.test.ts +2 -4
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/process-message-display-content.test.ts +2 -0
- package/src/__tests__/provider-error-scenarios.test.ts +5 -4
- package/src/__tests__/provider-usage-tracking.test.ts +39 -0
- package/src/__tests__/reaction-intercept-cold-cache-warm.test.ts +135 -0
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +158 -0
- package/src/__tests__/reaction-persistence.test.ts +51 -4
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +2 -0
- package/src/__tests__/registry.test.ts +4 -1
- package/src/__tests__/relay-server.test.ts +758 -32
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -12
- package/src/__tests__/secret-ingress-http.test.ts +14 -0
- package/src/__tests__/send-endpoint-busy.test.ts +30 -8
- package/src/__tests__/settings-routes.test.ts +32 -0
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +47 -2
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +79 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +49 -15
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +195 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +6 -7
- package/src/__tests__/subagent-notify-parent.test.ts +2 -0
- package/src/__tests__/subagent-role-registry.test.ts +24 -6
- package/src/__tests__/subagent-spawn-and-await.test.ts +546 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +2 -0
- package/src/__tests__/subagent-tools.test.ts +398 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/thread-backfill.test.ts +3 -3
- package/src/__tests__/title-generate-hook.test.ts +2 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +16 -11
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +2 -0
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +37 -51
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +12 -12
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -7
- package/src/__tests__/trusted-contact-multichannel.test.ts +16 -7
- package/src/__tests__/trusted-contact-verification.test.ts +79 -54
- package/src/__tests__/twilio-routes.test.ts +96 -0
- package/src/__tests__/ui-file-upload-surface.test.ts +86 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -0
- package/src/__tests__/voice-guardian-cold-cache-warm.test.ts +137 -0
- package/src/__tests__/voice-invite-redemption.test.ts +216 -20
- package/src/__tests__/web-search-backend-failure.test.ts +2 -0
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +3 -3
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +208 -0
- package/src/__tests__/workspace-migration-112-remove-advisor-callsite-override.test.ts +170 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +196 -238
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +14 -35
- package/src/__tests__/workspace-tool-loader.test.ts +195 -2
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +35 -47
- package/src/agent/loop-exclusive-tool.test.ts +154 -0
- package/src/agent/loop-native-web-search.test.ts +200 -0
- package/src/agent/loop.ts +164 -1
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/events/conversation-notice.ts +26 -0
- package/src/api/index.ts +19 -1
- package/src/api/responses/llm-request-log-entry.ts +29 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/api/surfaces.ts +39 -3
- package/src/approvals/guardian-channel-delivery.ts +30 -0
- package/src/approvals/guardian-expiry-notifier.ts +148 -0
- package/src/approvals/guardian-request-resolvers.ts +17 -15
- package/src/calls/__tests__/relay-setup-router.test.ts +267 -17
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +14 -9
- package/src/calls/inbound-trust-reader.ts +24 -2
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-access-wait.ts +6 -6
- package/src/calls/relay-server.ts +188 -51
- package/src/calls/relay-setup-router.ts +47 -17
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +14 -4
- package/src/channels/types.ts +10 -20
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/contacts.ts +10 -7
- package/src/cli/commands/db/__tests__/repair.test.ts +6 -5
- package/src/cli/commands/db/status.ts +37 -1
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/worker.test.ts +432 -0
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/worker.ts +242 -0
- package/src/cli/commands/plugins.ts +125 -13
- package/src/cli/lib/__tests__/install-from-github.test.ts +102 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/__tests__/publish-plugin.test.ts +404 -0
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/cli/lib/publish-plugin.ts +633 -0
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +16 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +27 -17
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +13 -3
- package/src/config/bundled-skills/subagent/SKILL.md +17 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +5 -4
- package/src/config/call-site-defaults.ts +0 -6
- package/src/config/feature-flag-registry.json +5 -13
- package/src/config/llm-resolver.ts +0 -3
- package/src/config/loader.ts +38 -5
- package/src/config/prune-seeded-callsite-defaults.ts +110 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/heartbeat.ts +2 -5
- package/src/config/schemas/llm.ts +3 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +8 -0
- package/src/config/seed-inference-profiles.ts +30 -34
- package/src/config/skills.ts +27 -5
- package/src/config/sync-gated-profiles.ts +12 -16
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +128 -0
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/__tests__/member-write-relay.test.ts +226 -0
- package/src/contacts/contact-store.ts +27 -237
- package/src/contacts/contacts-write.ts +18 -55
- package/src/contacts/gateway-channel-read.ts +51 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/contacts/member-write-relay.ts +183 -0
- package/src/contacts/types.ts +3 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +35 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +0 -44
- package/src/daemon/assistant-attachments.ts +27 -4
- package/src/daemon/conversation-agent-loop.ts +28 -0
- package/src/daemon/conversation-notices.ts +60 -0
- package/src/daemon/conversation-process.ts +35 -16
- package/src/daemon/conversation-surfaces.ts +111 -38
- package/src/daemon/conversation-tool-setup.ts +71 -30
- package/src/daemon/conversation.ts +23 -1
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.ts +28 -1
- package/src/daemon/external-plugins-bootstrap.ts +17 -41
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -2
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +25 -2
- package/src/daemon/handlers/__tests__/config-channels.test.ts +220 -0
- package/src/daemon/handlers/config-a2a.ts +6 -14
- package/src/daemon/handlers/config-channels.ts +67 -26
- package/src/daemon/handlers/conversations.ts +77 -0
- package/src/daemon/lifecycle.ts +16 -0
- package/src/daemon/mcp-reload-service.ts +10 -0
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/message-types/conversations.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/heartbeat/heartbeat-service.ts +5 -0
- package/src/home/relationship-state-writer.ts +5 -0
- package/src/hooks/hook-loader.ts +341 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +1 -0
- package/src/mcp/client.ts +15 -1
- package/src/mcp/mcp-auth-orchestrator.ts +6 -1
- package/src/mcp/mcp-header-store.ts +134 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -8
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +110 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/watchdog-events-store.test.ts +161 -0
- package/src/memory/compaction-ledger-store.ts +107 -0
- package/src/memory/conversation-crud.ts +129 -61
- package/src/memory/db-connection.ts +22 -3
- package/src/memory/db-init.ts +37 -503
- package/src/memory/db-singleton.ts +6 -4
- package/src/memory/jobs-worker.ts +104 -0
- package/src/memory/llm-request-log-store.ts +26 -1
- package/src/memory/llm-usage-store.ts +48 -20
- package/src/memory/memory-retrospective-job.ts +14 -8
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +152 -56
- package/src/memory/migrations/300-add-processing-started-at.ts +30 -0
- package/src/memory/migrations/301-create-watchdog-events.ts +45 -0
- package/src/memory/migrations/302-create-compaction-events.ts +107 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +297 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/run-migrations.ts +106 -10
- package/src/memory/migrations/validate-migration-state.ts +105 -67
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/schema/contacts.ts +6 -2
- package/src/memory/schema/conversations.ts +37 -0
- package/src/memory/schema/infrastructure.ts +20 -0
- package/src/memory/steps.ts +1294 -0
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/watchdog-events-store.ts +87 -0
- package/src/memory/worker-control.ts +204 -0
- package/src/memory/worker-process.ts +89 -0
- package/src/messaging/channel-binding-metadata.ts +31 -0
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/providers/slack/binding-metadata.ts +60 -0
- package/src/notifications/__tests__/broadcaster.test.ts +8 -8
- package/src/notifications/__tests__/connected-channels.test.ts +86 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +151 -0
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +53 -25
- package/src/notifications/emit-signal.ts +34 -15
- package/src/onboarding/checkin-event.test.ts +222 -0
- package/src/onboarding/checkin-event.ts +321 -0
- package/src/onboarding/schedule-checkin.ts +190 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +12 -12
- package/src/plugin-api/types.ts +12 -14
- package/src/plugin-api/vision-support.test.ts +28 -4
- package/src/plugin-api/vision-support.ts +66 -31
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/empty-response/hooks/stop.ts +2 -2
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +4 -3
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/history-repair/hooks/stop.ts +2 -2
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +47 -7
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +12 -13
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +14 -22
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +42 -11
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +2 -2
- package/src/plugins/defaults/index.ts +0 -35
- package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +33 -3
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +48 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +4 -8
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +43 -15
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +77 -13
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +12 -11
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +2 -2
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +2 -2
- package/src/plugins/defaults/title-generate/hooks/stop.ts +2 -2
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +2 -2
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +2 -2
- package/src/plugins/disabled-state.ts +31 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/mtime-cache.ts +186 -330
- package/src/plugins/pipeline.ts +111 -13
- package/src/plugins/registry.ts +59 -16
- package/src/plugins/surface-import.ts +121 -0
- package/src/plugins/types.ts +7 -9
- package/src/prompts/persona-resolver.ts +43 -11
- package/src/providers/anthropic/client.ts +5 -0
- package/src/providers/call-site-routing.ts +45 -0
- package/src/providers/model-catalog.ts +16 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +321 -0
- package/src/providers/openai/api-error-normalization.ts +270 -0
- package/src/providers/openai/chat-completions-provider.ts +37 -83
- package/src/providers/openai/responses-provider.ts +50 -46
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/provider-send-message.ts +10 -0
- package/src/providers/ratelimit.ts +10 -0
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +10 -0
- package/src/providers/types.ts +22 -0
- package/src/providers/usage-tracking.ts +10 -0
- package/src/runtime/__tests__/channel-verification-service.test.ts +133 -0
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +184 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +66 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +162 -0
- package/src/runtime/__tests__/member-verdict-cache.test.ts +119 -0
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +402 -123
- package/src/runtime/access-request-helper.ts +18 -39
- package/src/runtime/actor-trust-resolver.ts +46 -19
- package/src/runtime/anchored-guardian.test.ts +109 -0
- package/src/runtime/anchored-guardian.ts +86 -0
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-verification-service.ts +56 -31
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +69 -8
- package/src/runtime/invite-redemption-service.ts +213 -187
- package/src/runtime/local-actor-identity.test.ts +108 -0
- package/src/runtime/local-actor-identity.ts +85 -13
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/member-verdict-cache.ts +0 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +56 -5
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/contact-routes.test.ts +305 -0
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +92 -0
- package/src/runtime/routes/__tests__/http-adapter-actor-header.test.ts +129 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +188 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +13 -5
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +48 -57
- package/src/runtime/routes/conversation-cli-routes.ts +4 -5
- package/src/runtime/routes/conversation-list-routes.ts +4 -7
- package/src/runtime/routes/conversation-query-routes.ts +72 -0
- package/src/runtime/routes/conversation-routes.ts +84 -85
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +3 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -5
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +16 -1
- package/src/runtime/routes/identity-routes.ts +3 -2
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +97 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +61 -59
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +13 -5
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +19 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/llm-context-normalization.ts +83 -0
- package/src/runtime/routes/mcp-auth-routes.ts +171 -19
- package/src/runtime/routes/migration-rollback-routes.ts +4 -3
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/onboarding-checkin-routes.ts +86 -0
- package/src/runtime/routes/settings-routes.ts +8 -3
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +42 -56
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +13 -58
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +111 -40
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +35 -0
- package/src/{plugins/defaults/advisor/__tests__/transcript.test.ts → subagent/__tests__/consult-transcript.test.ts} +47 -10
- package/src/{plugins/defaults/advisor/steering.ts → subagent/consult-prompt.ts} +22 -32
- package/src/{plugins/defaults/advisor/transcript.ts → subagent/consult-transcript.ts} +18 -8
- package/src/subagent/index.ts +1 -1
- package/src/subagent/manager.ts +254 -33
- package/src/subagent/types.ts +11 -4
- package/src/telemetry/types.ts +34 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +87 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +29 -0
- package/src/tools/ask-question/ask-question-tool.ts +13 -0
- package/src/tools/executor.ts +4 -4
- package/src/tools/filesystem/search.ts +543 -0
- package/src/tools/registry.ts +38 -0
- package/src/tools/shared/filesystem/path-policy.ts +12 -5
- package/src/tools/subagent/consult-deadline.ts +49 -0
- package/src/tools/subagent/spawn.ts +234 -5
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +9 -2
- package/src/tools/tool-manifest.ts +3 -0
- package/src/tools/types.ts +131 -25
- package/src/tools/workspace-tools/loader.ts +348 -244
- package/src/util/errors.ts +26 -1
- package/src/util/logger.ts +9 -0
- package/src/util/platform.ts +19 -0
- package/src/util/telemetry-db-path.ts +24 -0
- package/src/workflows/library.test.ts +140 -0
- package/src/workflows/library.ts +82 -28
- package/src/workspace/migrations/017-seed-persona-dirs.ts +3 -34
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +3 -24
- package/src/workspace/migrations/031-drop-user-md.ts +232 -148
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +14 -66
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +134 -0
- package/src/workspace/migrations/112-remove-advisor-callsite-override.ts +64 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +0 -70
- package/src/daemon/workspace-tools-watcher.ts +0 -328
- package/src/memory/migrations/registry.ts +0 -573
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +0 -56
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +0 -43
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +0 -137
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -153
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +0 -138
- package/src/plugins/defaults/advisor/advisor-gate.ts +0 -29
- package/src/plugins/defaults/advisor/advisor-state-store.ts +0 -94
- package/src/plugins/defaults/advisor/config.ts +0 -21
- package/src/plugins/defaults/advisor/consult.ts +0 -93
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +0 -34
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +0 -30
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +0 -19
- package/src/plugins/defaults/advisor/package.json +0 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +0 -65
- package/src/providers/openai/__tests__/api-error-detail.test.ts +0 -120
package/bun.lock
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"playwright": "1.58.2",
|
|
39
39
|
"postgres": "3.4.8",
|
|
40
40
|
"quickjs-emscripten": "0.32.0",
|
|
41
|
+
"re2js": "2.8.3",
|
|
41
42
|
"rrule": "2.8.1",
|
|
42
43
|
"semver": "7.8.0",
|
|
43
44
|
"stemmer": "2.0.1",
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
"@types/node": "25.5.0",
|
|
55
56
|
"@types/semver": "7.5.8",
|
|
56
57
|
"@types/uuid": "10.0.0",
|
|
58
|
+
"@typescript/native-preview": "7.0.0-dev.20260624.1",
|
|
57
59
|
"ajv": "8.18.0",
|
|
58
60
|
"drizzle-kit": "0.31.10",
|
|
59
61
|
"eslint": "10.0.3",
|
|
@@ -454,6 +456,22 @@
|
|
|
454
456
|
|
|
455
457
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.0", "", { "dependencies": { "@typescript-eslint/types": "8.57.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg=="],
|
|
456
458
|
|
|
459
|
+
"@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260624.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260624.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260624.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260624.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260624.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260624.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260624.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260624.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-ogwfNo1xuAutOF8RbTCo3Ut0q/65u2ucOeHizi6O14q+3vnelNS+u8qVC2QWXubMcwtuN5E9cbfPslvGC4kdwA=="],
|
|
460
|
+
|
|
461
|
+
"@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260624.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-g8CqDkYCHTCYdhBHXs5cMraBurOS+KrcMFxE0SsaKZoI6Tnp+le1aWvxUBbzNKJYyThHJqb/1mLopzEJxJCuKA=="],
|
|
462
|
+
|
|
463
|
+
"@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260624.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-P00JVvSV90eioYDuINAKmOSA8yhFTWLq6RvS5lrCfUuDlcgr2kSOgZAfFHIksHBVz6ZXpAXpa0dHPmc5SJ3Ymw=="],
|
|
464
|
+
|
|
465
|
+
"@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260624.1", "", { "os": "linux", "cpu": "arm" }, "sha512-eWHELvfQMkVRjafMd+3ATgM9p9yAergJaM4AOY8AekCNWnHFwUrp/ohh+ryyMUIqque5jjb/kuTiOiGj728I2Q=="],
|
|
466
|
+
|
|
467
|
+
"@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260624.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cppM2yTZ/Gd1hOXy8NEJcUBxJ0O0zl9CU3OU1ZWZ/OHWWX/ukEzCCr94SUwJhjIWOylBCpIYkrvYoTwxNa94XQ=="],
|
|
468
|
+
|
|
469
|
+
"@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260624.1", "", { "os": "linux", "cpu": "x64" }, "sha512-FaB8rS+rKYz4nDrEsHsF3b4cn7eCKCYroMJReA375OuQ6PHcmCNQ6QlVetA0dfFBxTTgejmoKyfw9xgAA5P4Yw=="],
|
|
470
|
+
|
|
471
|
+
"@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260624.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-BgkqbCmSHDb5UxqWaFlFFJ/DHNT3lEUO4W8627ap6+QthJZuXk2imiHAX3PgYXC6en9fLLyR6jjcseAa4CCshg=="],
|
|
472
|
+
|
|
473
|
+
"@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260624.1", "", { "os": "win32", "cpu": "x64" }, "sha512-WaZ+ue63NgB2j/lqjirfevh/TqcsCxSqnKhGGiRnlxHyYIBcoq+x7KngyEnyGIaywJE1PcFeXA+2EMSIPlSEiQ=="],
|
|
474
|
+
|
|
457
475
|
"@vellumai/ces-client": ["@vellumai/ces-client@file:../packages/ces-client", { "dependencies": { "@vellumai/service-contracts": "file:../service-contracts" }, "devDependencies": { "@types/bun": "1.2.4", "typescript": "5.7.3" } }],
|
|
458
476
|
|
|
459
477
|
"@vellumai/credential-storage": ["@vellumai/credential-storage@file:../packages/credential-storage", { "devDependencies": { "@types/bun": "1.3.10", "typescript": "5.9.3" } }],
|
|
@@ -1040,6 +1058,8 @@
|
|
|
1040
1058
|
|
|
1041
1059
|
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
|
|
1042
1060
|
|
|
1061
|
+
"re2js": ["re2js@2.8.3", "", {}, "sha512-lUKeXVwMqU302DM/WaOm33XF2hhzjGUZ8CbLg4zSAMpW2PPkJ2+is25AROevNiw+DytFmKU5gsQ92cB1Kxy+fA=="],
|
|
1062
|
+
|
|
1043
1063
|
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
|
1044
1064
|
|
|
1045
1065
|
"real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
|
package/docs/workspace-tools.md
CHANGED
|
@@ -5,9 +5,9 @@ add a brand-new one) by dropping a single file under their
|
|
|
5
5
|
`<workspaceDir>/tools/` directory. The override survives assistant restarts,
|
|
6
6
|
takes effect during the same startup phase as core tool initialization,
|
|
7
7
|
and is recoverable: removing the file restores the original core behavior.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Overrides are reconciled from disk on every conversation read, so edits
|
|
9
|
+
under `tools/` take effect on the next conversation with no restart and no
|
|
10
|
+
filesystem watcher.
|
|
11
11
|
|
|
12
12
|
This page explains the file convention, lifecycle position, and the
|
|
13
13
|
"single canonical source per name" invariant the design is built around.
|
|
@@ -100,8 +100,8 @@ Workspace tools are the highest-priority origin in the tool registry:
|
|
|
100
100
|
|
|
101
101
|
- **Same name as a core tool** → the original core tool is moved into an
|
|
102
102
|
internal stash (`getCoreToolOverride(name)`) and the workspace tool takes
|
|
103
|
-
its place. Removing the workspace file
|
|
104
|
-
|
|
103
|
+
its place. Removing the workspace file restores the original on the next
|
|
104
|
+
reconcile — workspace tools are not destructive to the core baseline.
|
|
105
105
|
- **Brand-new name** → registers as a net-new entry. No stash.
|
|
106
106
|
- **`<name>.removed` sentinel for a core tool** → the core tool is
|
|
107
107
|
stripped (stashed in the same map as override-style stashing) and no
|
|
@@ -128,35 +128,44 @@ on the incoming tool.
|
|
|
128
128
|
|
|
129
129
|
```
|
|
130
130
|
initializeTools() # core tools register
|
|
131
|
-
→ loadWorkspaceTools() # initial workspace tool
|
|
131
|
+
→ loadWorkspaceTools() # initial workspace tool reconcile
|
|
132
132
|
→ MCP tool registration
|
|
133
133
|
→ loadUserPlugins()
|
|
134
134
|
→ bootstrapPlugins()
|
|
135
135
|
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
→
|
|
136
|
+
# on every conversation turn (createResolveToolsCallback):
|
|
137
|
+
resolveTools(history)
|
|
138
|
+
→ loadWorkspaceTools() # reconcile registry against disk (fire-and-forget)
|
|
139
|
+
→ getWorkspaceToolDefinitions() # re-read workspace tools from the registry
|
|
140
|
+
→ getMcpToolDefinitions() # re-read MCP tools (same pattern)
|
|
139
141
|
```
|
|
140
142
|
|
|
141
143
|
Workspace tools register _after_ core tools and _before_ every other
|
|
142
|
-
extension surface during the initial
|
|
143
|
-
registration sees the workspace tool as already-owned. The initial
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
144
|
+
extension surface during the initial reconcile so that every subsequent
|
|
145
|
+
registration sees the workspace tool as already-owned. The initial
|
|
146
|
+
reconcile always runs at boot, so workspace tools load from disk at every
|
|
147
|
+
startup.
|
|
148
|
+
|
|
149
|
+
There is no filesystem watcher. Instead, `loadWorkspaceTools()` is
|
|
150
|
+
idempotent and is re-invoked by the per-turn tool resolver
|
|
151
|
+
(`createResolveToolsCallback`), which then re-reads workspace tools from
|
|
152
|
+
the registry the same way it re-reads MCP tools. Each reconcile re-derives
|
|
153
|
+
the world from disk ("given what's on disk right now under `tools/`, what
|
|
154
|
+
registry state should the assistant be in?") and applies the delta —
|
|
155
|
+
registering added files, re-importing changed files, unregistering deleted
|
|
156
|
+
files, and restoring core tools whose `.removed` sentinel was deleted. A
|
|
157
|
+
conversation therefore picks up on-disk edits on its next turn, with no
|
|
158
|
+
restart and without being recreated.
|
|
159
|
+
|
|
160
|
+
The reconcile is fire-and-forget and eventually consistent: an edit lands
|
|
161
|
+
in the registry during one turn's reconcile and is read on a subsequent
|
|
162
|
+
turn. Unchanged files are skipped via an mtime cache, so a no-op reconcile
|
|
163
|
+
costs one `readdir` plus a `stat` per file and never re-imports. Concurrent
|
|
164
|
+
callers coalesce onto a single in-flight reconcile so their
|
|
165
|
+
unregister/register sequences never interleave. This is the same
|
|
166
|
+
eventual-consistency, re-derive-from-disk approach the plugin loader's
|
|
167
|
+
mtime cache uses, with the per-turn tool read — rather than a watcher —
|
|
168
|
+
kicking the reconcile.
|
|
160
169
|
|
|
161
170
|
## Per-tool isolation
|
|
162
171
|
|
|
@@ -182,15 +191,15 @@ the whole call without partially populating the registry.
|
|
|
182
191
|
|
|
183
192
|
## Unregistering
|
|
184
193
|
|
|
185
|
-
Deleting `<workspaceDir>/tools/<name>.{ts,js,json}`
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
required.
|
|
194
|
+
Deleting `<workspaceDir>/tools/<name>.{ts,js,json}` is picked up by the
|
|
195
|
+
next reconcile, which calls `unregisterWorkspaceTool(name)` and restores
|
|
196
|
+
the stashed core tool when one exists, or simply deletes the entry when
|
|
197
|
+
the workspace tool was net-new. The change takes effect on the next
|
|
198
|
+
conversation — no assistant restart is required.
|
|
190
199
|
|
|
191
200
|
To strip a core tool without substituting a replacement, drop an empty
|
|
192
201
|
`<workspaceDir>/tools/<name>.removed` file. Removing that sentinel
|
|
193
202
|
restores the core tool on the next reconcile. The two states (override
|
|
194
203
|
vs. strip) are mutually exclusive — placing both `<name>.ts` and
|
|
195
|
-
`<name>.removed` for the same stem causes the
|
|
204
|
+
`<name>.removed` for the same stem causes the reconcile to tear down
|
|
196
205
|
both states until the conflict is resolved on disk.
|
|
@@ -51,11 +51,17 @@ const ALLOWED_PREFIXES = {
|
|
|
51
51
|
"../../config/schema",
|
|
52
52
|
"../../config/env",
|
|
53
53
|
"../../util/platform",
|
|
54
|
+
"../../../util/platform",
|
|
54
55
|
// Memory retrospective — the retrospective CLI runs the fork-based
|
|
55
56
|
// retrospective in-process (no daemon, no IPC), so it imports the
|
|
56
57
|
// job handler directly. Depth-2 for commands/memory/ nesting.
|
|
57
58
|
"../../memory/memory-retrospective-job",
|
|
58
59
|
"../../../memory/memory-retrospective-job",
|
|
60
|
+
// Memory worker control — the `memory worker` CLI spawns/probes/stops
|
|
61
|
+
// the worker OS process directly (no daemon, no IPC), so it imports the
|
|
62
|
+
// shared PID-file control helpers. Depth-2 for commands/memory/ nesting.
|
|
63
|
+
"../../memory/worker-control",
|
|
64
|
+
"../../../memory/worker-control",
|
|
59
65
|
"../logger",
|
|
60
66
|
"../output",
|
|
61
67
|
"../../logger",
|
package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the guardian binding + delivery pull contract.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
GuardianDeliverySchema,
|
|
9
|
+
ResolveGuardianDeliveryRequestSchema,
|
|
10
|
+
type GuardianDelivery,
|
|
11
|
+
} from "../guardian-delivery-contract.js";
|
|
12
|
+
|
|
13
|
+
const fullGuardian: GuardianDelivery = {
|
|
14
|
+
channelType: "imessage",
|
|
15
|
+
contactId: "c1",
|
|
16
|
+
principalId: "p1",
|
|
17
|
+
displayName: "Guardian Name",
|
|
18
|
+
address: "+15555550100",
|
|
19
|
+
externalChatId: "ext-chat-1",
|
|
20
|
+
status: "active",
|
|
21
|
+
verifiedAt: 1699999999,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("ResolveGuardianDeliveryRequestSchema", () => {
|
|
25
|
+
test("parses with channelTypes", () => {
|
|
26
|
+
const req = { channelTypes: ["imessage", "sms"] };
|
|
27
|
+
expect(ResolveGuardianDeliveryRequestSchema.parse(req)).toEqual(req);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("parses with channelTypes omitted", () => {
|
|
31
|
+
expect(ResolveGuardianDeliveryRequestSchema.parse({})).toEqual({});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("defaults to {} when params are undefined (no-param IPC call)", () => {
|
|
35
|
+
expect(ResolveGuardianDeliveryRequestSchema.parse(undefined)).toEqual({});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("GuardianDeliverySchema", () => {
|
|
40
|
+
test("round-trips a fully-populated row", () => {
|
|
41
|
+
expect(GuardianDeliverySchema.parse(fullGuardian)).toEqual(fullGuardian);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("requires channelType", () => {
|
|
45
|
+
const { channelType: _omit, ...rest } = fullGuardian;
|
|
46
|
+
expect(() => GuardianDeliverySchema.parse(rest)).toThrow();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("requires contactId", () => {
|
|
50
|
+
const { contactId: _omit, ...rest } = fullGuardian;
|
|
51
|
+
expect(() => GuardianDeliverySchema.parse(rest)).toThrow();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("requires address", () => {
|
|
55
|
+
const { address: _omit, ...rest } = fullGuardian;
|
|
56
|
+
expect(() => GuardianDeliverySchema.parse(rest)).toThrow();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("requires status", () => {
|
|
60
|
+
const { status: _omit, ...rest } = fullGuardian;
|
|
61
|
+
expect(() => GuardianDeliverySchema.parse(rest)).toThrow();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("optional fields accept null", () => {
|
|
65
|
+
const row = {
|
|
66
|
+
channelType: "imessage",
|
|
67
|
+
contactId: "c1",
|
|
68
|
+
address: "+15555550100",
|
|
69
|
+
status: "active",
|
|
70
|
+
principalId: null,
|
|
71
|
+
displayName: null,
|
|
72
|
+
externalChatId: null,
|
|
73
|
+
verifiedAt: null,
|
|
74
|
+
} satisfies GuardianDelivery;
|
|
75
|
+
expect(GuardianDeliverySchema.parse(row)).toEqual(row);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("optional fields accept undefined (omitted)", () => {
|
|
79
|
+
const row = {
|
|
80
|
+
channelType: "imessage",
|
|
81
|
+
contactId: "c1",
|
|
82
|
+
address: "+15555550100",
|
|
83
|
+
status: "active",
|
|
84
|
+
} satisfies GuardianDelivery;
|
|
85
|
+
const parsed = GuardianDeliverySchema.parse(row);
|
|
86
|
+
expect(parsed.principalId).toBeUndefined();
|
|
87
|
+
expect(parsed.displayName).toBeUndefined();
|
|
88
|
+
expect(parsed.externalChatId).toBeUndefined();
|
|
89
|
+
expect(parsed.verifiedAt).toBeUndefined();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -7,6 +7,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
7
7
|
|
|
8
8
|
import { SourceMetadataSchema } from "../inbound-contract.js";
|
|
9
9
|
import {
|
|
10
|
+
makeResolutionFailedVerdict,
|
|
10
11
|
TrustVerdictSchema,
|
|
11
12
|
type TrustVerdict,
|
|
12
13
|
} from "../trust-verdict-contract.js";
|
|
@@ -43,6 +44,36 @@ describe("TrustVerdictSchema", () => {
|
|
|
43
44
|
expect(TrustVerdictSchema.parse(minimal)).toEqual(minimal);
|
|
44
45
|
});
|
|
45
46
|
|
|
47
|
+
test("parses a verdict carrying resolutionFailed", () => {
|
|
48
|
+
const verdict = {
|
|
49
|
+
trustClass: "unknown",
|
|
50
|
+
canonicalSenderId: null,
|
|
51
|
+
resolutionFailed: true,
|
|
52
|
+
} satisfies TrustVerdict;
|
|
53
|
+
expect(TrustVerdictSchema.parse(verdict)).toEqual(verdict);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("leaves resolutionFailed undefined when absent", () => {
|
|
57
|
+
const parsed = TrustVerdictSchema.parse({
|
|
58
|
+
trustClass: "unknown",
|
|
59
|
+
canonicalSenderId: null,
|
|
60
|
+
});
|
|
61
|
+
expect(parsed.resolutionFailed).toBeUndefined();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("makeResolutionFailedVerdict builds an unknown sentinel", () => {
|
|
65
|
+
expect(makeResolutionFailedVerdict("+15555550100")).toEqual({
|
|
66
|
+
trustClass: "unknown",
|
|
67
|
+
canonicalSenderId: "+15555550100",
|
|
68
|
+
resolutionFailed: true,
|
|
69
|
+
});
|
|
70
|
+
expect(makeResolutionFailedVerdict(null)).toEqual({
|
|
71
|
+
trustClass: "unknown",
|
|
72
|
+
canonicalSenderId: null,
|
|
73
|
+
resolutionFailed: true,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
46
77
|
test("rejects an invalid trustClass", () => {
|
|
47
78
|
expect(() =>
|
|
48
79
|
TrustVerdictSchema.parse({
|
|
@@ -137,6 +137,50 @@ export type MarkChannelVerifiedIpcResponse = z.infer<
|
|
|
137
137
|
typeof MarkChannelVerifiedIpcResponseSchema
|
|
138
138
|
>;
|
|
139
139
|
|
|
140
|
+
export const UpsertVerifiedChannelIpcParamsSchema = z.object({
|
|
141
|
+
type: z.string().min(1),
|
|
142
|
+
address: z.string().min(1),
|
|
143
|
+
externalChatId: z.string().min(1),
|
|
144
|
+
displayName: z.string().optional(),
|
|
145
|
+
username: z.string().optional(),
|
|
146
|
+
// Audit source for the verification. Free text (DB column is text) so the
|
|
147
|
+
// invite-activation path can pass "invite"; do not narrow to an enum.
|
|
148
|
+
verifiedVia: z.string().optional(),
|
|
149
|
+
// Target contact to bind the channel to (invite redemption). When set, an
|
|
150
|
+
// existing channel for the same (type,address) under a different contact is
|
|
151
|
+
// reassigned to this contact, mirroring the assistant's
|
|
152
|
+
// reassignConflictingChannels.
|
|
153
|
+
contactId: z.string().min(1).optional(),
|
|
154
|
+
// Relax the revoked refusal guard so a valid invite can reactivate a revoked
|
|
155
|
+
// member. Blocked actors are refused regardless.
|
|
156
|
+
allowRevokedReactivation: z.boolean().optional(),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
export type UpsertVerifiedChannelIpcParams = z.infer<
|
|
160
|
+
typeof UpsertVerifiedChannelIpcParamsSchema
|
|
161
|
+
>;
|
|
162
|
+
|
|
163
|
+
export const UpsertVerifiedChannelIpcResponseSchema = z.object({
|
|
164
|
+
ok: z.boolean(),
|
|
165
|
+
verified: z.boolean(),
|
|
166
|
+
// Present only when verified — a blocked/revoked skip omits the channel.
|
|
167
|
+
channel: z
|
|
168
|
+
.object({
|
|
169
|
+
id: z.string(),
|
|
170
|
+
contactId: z.string(),
|
|
171
|
+
type: z.string(),
|
|
172
|
+
address: z.string(),
|
|
173
|
+
status: z.string(),
|
|
174
|
+
verifiedAt: z.number().nullable(),
|
|
175
|
+
verifiedVia: z.string().nullable(),
|
|
176
|
+
})
|
|
177
|
+
.optional(),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
export type UpsertVerifiedChannelIpcResponse = z.infer<
|
|
181
|
+
typeof UpsertVerifiedChannelIpcResponseSchema
|
|
182
|
+
>;
|
|
183
|
+
|
|
140
184
|
export const MarkChannelRevokedIpcParamsSchema = z.object({
|
|
141
185
|
contactChannelId: z.string().min(1),
|
|
142
186
|
// Audit reason for the downgrade. The verification-revoke flow passes
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contract for the gateway-owned guardian binding + delivery pull.
|
|
3
|
+
*
|
|
4
|
+
* The gateway resolves the active guardian binding(s) and their per-channel
|
|
5
|
+
* delivery endpoints from its DB; the daemon pulls them via the
|
|
6
|
+
* `resolve_guardian_delivery` IPC route. INFO (notes / userFile) is NOT
|
|
7
|
+
* carried here — the daemon joins it locally by `contactId`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* IPC request for `resolve_guardian_delivery`. `channelTypes` is an optional
|
|
14
|
+
* filter; omitted ⇒ all active guardian channels.
|
|
15
|
+
*/
|
|
16
|
+
export const ResolveGuardianDeliveryRequestSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
channelTypes: z.array(z.string()).optional(),
|
|
19
|
+
})
|
|
20
|
+
.default({});
|
|
21
|
+
|
|
22
|
+
export type ResolveGuardianDeliveryRequest = z.infer<
|
|
23
|
+
typeof ResolveGuardianDeliveryRequestSchema
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* One active guardian binding + delivery endpoint for a single channel.
|
|
28
|
+
*/
|
|
29
|
+
export const GuardianDeliverySchema = z.object({
|
|
30
|
+
channelType: z.string(),
|
|
31
|
+
contactId: z.string(),
|
|
32
|
+
principalId: z.string().nullable().optional(),
|
|
33
|
+
displayName: z.string().nullable().optional(),
|
|
34
|
+
address: z.string(),
|
|
35
|
+
externalChatId: z.string().nullable().optional(),
|
|
36
|
+
status: z.string(),
|
|
37
|
+
verifiedAt: z.number().nullable().optional(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export type GuardianDelivery = z.infer<typeof GuardianDeliverySchema>;
|
|
41
|
+
|
|
42
|
+
export const ResolveGuardianDeliveryResponseSchema = z.object({
|
|
43
|
+
guardians: z.array(GuardianDeliverySchema),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export type ResolveGuardianDeliveryResponse = z.infer<
|
|
47
|
+
typeof ResolveGuardianDeliveryResponseSchema
|
|
48
|
+
>;
|
|
@@ -73,6 +73,7 @@ export type { AdmissionPolicy } from "./admission-policy-contract.js";
|
|
|
73
73
|
|
|
74
74
|
// Trust verdict contract (gateway → daemon) — Zod schemas + derived types
|
|
75
75
|
export {
|
|
76
|
+
makeResolutionFailedVerdict,
|
|
76
77
|
ResolveInboundTrustRequestSchema,
|
|
77
78
|
TRUST_CLASS_VALUES,
|
|
78
79
|
TrustClassSchema,
|
|
@@ -84,3 +85,16 @@ export type {
|
|
|
84
85
|
TrustClass,
|
|
85
86
|
TrustVerdict,
|
|
86
87
|
} from "./trust-verdict-contract.js";
|
|
88
|
+
|
|
89
|
+
// Guardian delivery contract (daemon → gateway pull) — Zod schemas + derived types
|
|
90
|
+
export {
|
|
91
|
+
GuardianDeliverySchema,
|
|
92
|
+
ResolveGuardianDeliveryRequestSchema,
|
|
93
|
+
ResolveGuardianDeliveryResponseSchema,
|
|
94
|
+
} from "./guardian-delivery-contract.js";
|
|
95
|
+
|
|
96
|
+
export type {
|
|
97
|
+
GuardianDelivery,
|
|
98
|
+
ResolveGuardianDeliveryRequest,
|
|
99
|
+
ResolveGuardianDeliveryResponse,
|
|
100
|
+
} from "./guardian-delivery-contract.js";
|
|
@@ -42,6 +42,11 @@ export const TrustVerdictSchema = z.object({
|
|
|
42
42
|
trustClass: TrustClassSchema,
|
|
43
43
|
canonicalSenderId: z.string().nullable(),
|
|
44
44
|
|
|
45
|
+
// Present+true ⇒ gateway attempted resolution but failed (DB error);
|
|
46
|
+
// consumer treats it as "could not vouch", distinct from a real `unknown`
|
|
47
|
+
// stranger.
|
|
48
|
+
resolutionFailed: z.boolean().optional(),
|
|
49
|
+
|
|
45
50
|
// Guardian binding — present only when a guardian binding matches.
|
|
46
51
|
guardianExternalUserId: z.string().optional(),
|
|
47
52
|
guardianDeliveryChatId: z.string().nullable().optional(),
|
|
@@ -63,6 +68,18 @@ export const TrustVerdictSchema = z.object({
|
|
|
63
68
|
|
|
64
69
|
export type TrustVerdict = z.infer<typeof TrustVerdictSchema>;
|
|
65
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Sentinel for a gateway resolver failure; consumers treat it as
|
|
73
|
+
* could-not-vouch (distinct from a real `unknown` stranger). Takes the
|
|
74
|
+
* already-canonicalized sender id so this module stays free of the gateway's
|
|
75
|
+
* canonicalization util.
|
|
76
|
+
*/
|
|
77
|
+
export function makeResolutionFailedVerdict(
|
|
78
|
+
canonicalSenderId: string | null,
|
|
79
|
+
): TrustVerdict {
|
|
80
|
+
return { trustClass: "unknown", canonicalSenderId, resolutionFailed: true };
|
|
81
|
+
}
|
|
82
|
+
|
|
66
83
|
/**
|
|
67
84
|
* IPC request for `resolve_inbound_trust`. Per-actor identity keys the
|
|
68
85
|
* gateway resolver needs to classify the inbound sender. The response reuses
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { CHANNEL_IDS, isChannelId } from "../channels.js";
|
|
4
|
+
|
|
5
|
+
describe("isChannelId", () => {
|
|
6
|
+
test("accepts every canonical channel id", () => {
|
|
7
|
+
for (const id of CHANNEL_IDS) {
|
|
8
|
+
expect(isChannelId(id)).toBe(true);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("includes the internal channels no external surface ingresses", () => {
|
|
13
|
+
// `platform` (control plane) and `vellum` (native app) are part of the
|
|
14
|
+
// canonical vocabulary even though the gateway never ingresses them. The
|
|
15
|
+
// gateway's narrower list is a compile-time-asserted subset of this set,
|
|
16
|
+
// so these must remain canonical for that assertion to mean anything.
|
|
17
|
+
expect(isChannelId("platform")).toBe(true);
|
|
18
|
+
expect(isChannelId("vellum")).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("rejects unknown strings and non-string values", () => {
|
|
22
|
+
expect(isChannelId("discord")).toBe(false);
|
|
23
|
+
expect(isChannelId("")).toBe(false);
|
|
24
|
+
expect(isChannelId(undefined)).toBe(false);
|
|
25
|
+
expect(isChannelId(null)).toBe(false);
|
|
26
|
+
expect(isChannelId(42)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical channel-id vocabulary shared between the assistant daemon and the
|
|
3
|
+
* gateway.
|
|
4
|
+
*
|
|
5
|
+
* A "channel" is an external messaging surface an actor can reach the
|
|
6
|
+
* assistant through (Slack, Telegram, WhatsApp, phone, …) plus a couple of
|
|
7
|
+
* internal ids (`vellum` for native app conversations, `platform` for the
|
|
8
|
+
* internal control plane). This is the single source of truth for that set:
|
|
9
|
+
* the assistant adopts it wholesale as its `ChannelId`, and the gateway
|
|
10
|
+
* asserts its own (narrower) inbound list is a subset of it so the two sides
|
|
11
|
+
* cannot silently drift.
|
|
12
|
+
*
|
|
13
|
+
* Both packages depend on `@vellumai/service-contracts`, so hoisting the set
|
|
14
|
+
* here (rather than maintaining a copy on each side) means adding or renaming
|
|
15
|
+
* a channel happens in exactly one place.
|
|
16
|
+
*
|
|
17
|
+
* Note that a consumer may legitimately handle only a *subset* of these — the
|
|
18
|
+
* gateway, for example, never ingresses `platform`. Use a local list guarded
|
|
19
|
+
* by `satisfies readonly ChannelId[]` for those cases rather than redefining
|
|
20
|
+
* the union.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export const CHANNEL_IDS = [
|
|
24
|
+
"telegram",
|
|
25
|
+
"phone",
|
|
26
|
+
"vellum",
|
|
27
|
+
"whatsapp",
|
|
28
|
+
"slack",
|
|
29
|
+
"email",
|
|
30
|
+
"platform",
|
|
31
|
+
"a2a",
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
export type ChannelId = (typeof CHANNEL_IDS)[number];
|
|
35
|
+
|
|
36
|
+
export function isChannelId(value: unknown): value is ChannelId {
|
|
37
|
+
return (
|
|
38
|
+
typeof value === "string" &&
|
|
39
|
+
(CHANNEL_IDS as readonly string[]).includes(value)
|
|
40
|
+
);
|
|
41
|
+
}
|