@vellumai/assistant 0.9.0 → 0.10.0-staging.2
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 +18 -34
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +976 -63
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +51 -1
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +49 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +197 -4
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +105 -17
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +27 -14
- package/src/daemon/conversation.ts +66 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +202 -3
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +33 -0
- package/src/tools/subagent/spawn.ts +61 -12
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
type FeedItemCategory,
|
|
16
16
|
type FeedItemDetailPanelKind,
|
|
17
17
|
feedItemSchema,
|
|
18
|
-
type FeedItemUrgency,
|
|
19
18
|
} from "../home/feed-types.js";
|
|
20
19
|
import { appendFeedItem } from "../home/feed-writer.js";
|
|
21
20
|
import { getConversation } from "../memory/conversation-crud.js";
|
|
@@ -28,13 +27,6 @@ import type { NotificationDecision, RenderedChannelCopy } from "./types.js";
|
|
|
28
27
|
|
|
29
28
|
const log = getLogger("home-feed-side-effect");
|
|
30
29
|
|
|
31
|
-
const FEED_ITEM_URGENCIES: ReadonlySet<string> = new Set<FeedItemUrgency>([
|
|
32
|
-
"low",
|
|
33
|
-
"medium",
|
|
34
|
-
"high",
|
|
35
|
-
"critical",
|
|
36
|
-
]);
|
|
37
|
-
|
|
38
30
|
/**
|
|
39
31
|
* Append a `FeedItem` for the given notification signal when the
|
|
40
32
|
* filter criteria pass.
|
|
@@ -97,9 +89,7 @@ export async function writeHomeFeedItemForSignal(
|
|
|
97
89
|
return null;
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
const urgency =
|
|
101
|
-
? (signal.attentionHints.urgency as FeedItemUrgency)
|
|
102
|
-
: undefined;
|
|
92
|
+
const urgency = signal.attentionHints.urgency;
|
|
103
93
|
const now = new Date().toISOString();
|
|
104
94
|
|
|
105
95
|
const category = deriveCategory(signal);
|
|
@@ -109,7 +99,7 @@ export async function writeHomeFeedItemForSignal(
|
|
|
109
99
|
signal.contextPayload &&
|
|
110
100
|
typeof signal.contextPayload === "object" &&
|
|
111
101
|
!Array.isArray(signal.contextPayload)
|
|
112
|
-
? { ...
|
|
102
|
+
? { ...signal.contextPayload }
|
|
113
103
|
: undefined;
|
|
114
104
|
|
|
115
105
|
// Link scheduled-run notifications back to their schedule. `notify`-mode
|
|
@@ -187,7 +177,7 @@ function deriveDetailPanelKind(
|
|
|
187
177
|
const payload = signal.contextPayload;
|
|
188
178
|
const kind =
|
|
189
179
|
payload && typeof payload === "object" && "requestKind" in payload
|
|
190
|
-
?
|
|
180
|
+
? payload.requestKind
|
|
191
181
|
: undefined;
|
|
192
182
|
if (kind === "tool_approval" || kind === "tool_grant_request") {
|
|
193
183
|
return "permissionChat";
|
|
@@ -217,9 +207,10 @@ function resolveHomeFeedMirror(
|
|
|
217
207
|
sourceConversationId?: string;
|
|
218
208
|
sourceScheduleJobId?: string;
|
|
219
209
|
} {
|
|
220
|
-
let sourceRow:
|
|
221
|
-
|
|
222
|
-
|
|
210
|
+
let sourceRow: {
|
|
211
|
+
conversationType?: string;
|
|
212
|
+
scheduleJobId?: string | null;
|
|
213
|
+
} | null = null;
|
|
223
214
|
if (signal.sourceContextId) {
|
|
224
215
|
try {
|
|
225
216
|
sourceRow = getConversation(signal.sourceContextId) ?? null;
|
|
@@ -24,43 +24,42 @@ export function readPayloadString(
|
|
|
24
24
|
payload: unknown,
|
|
25
25
|
key: string,
|
|
26
26
|
): string | undefined {
|
|
27
|
-
if (!payload || typeof payload !== "object"
|
|
27
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
28
|
+
return undefined;
|
|
28
29
|
const value = (payload as Record<string, unknown>)[key];
|
|
29
30
|
return typeof value === "string" ? value : undefined;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/** Truncate `text` to `maxLength`, appending "…" when exceeded. */
|
|
34
|
+
export function truncate(text: string, maxLength: number): string {
|
|
35
|
+
if (text.length <= maxLength) return text;
|
|
36
|
+
return text.slice(0, maxLength - 1) + "…";
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
// ── Sanitization ────────────────────────────────────────────────────────────
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
/** Strip control characters and newlines, then truncate to `maxLength`. */
|
|
42
|
+
function sanitize(value: string, maxLength: number): string {
|
|
43
|
+
return truncate(
|
|
44
|
+
value.replace(/[\x00-\x1f\x7f-\x9f\r\n]+/g, " ").trim(),
|
|
45
|
+
maxLength,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
35
48
|
|
|
36
49
|
/**
|
|
37
50
|
* Sanitize an untrusted identity field for inclusion in notification copy.
|
|
38
|
-
*
|
|
39
|
-
* - Strips control characters (U+0000–U+001F, U+007F–U+009F) and newlines.
|
|
40
|
-
* - Clamps to 120 characters.
|
|
51
|
+
* Strips control characters and clamps to 120 characters.
|
|
41
52
|
*/
|
|
42
53
|
export function sanitizeIdentityField(value: string): string {
|
|
43
|
-
|
|
44
|
-
const clamped =
|
|
45
|
-
stripped.length > IDENTITY_FIELD_MAX_LENGTH
|
|
46
|
-
? stripped.slice(0, IDENTITY_FIELD_MAX_LENGTH) + "…"
|
|
47
|
-
: stripped;
|
|
48
|
-
return clamped;
|
|
54
|
+
return sanitize(value, 120);
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
export const MESSAGE_PREVIEW_MAX_LENGTH = 200;
|
|
52
58
|
|
|
53
59
|
/**
|
|
54
60
|
* Sanitize an untrusted message preview for inclusion in notification copy.
|
|
55
|
-
*
|
|
56
|
-
* Same as {@link sanitizeIdentityField} but uses a higher length limit
|
|
57
|
-
* (200 chars) suited for message previews.
|
|
61
|
+
* Strips control characters and clamps to 200 characters.
|
|
58
62
|
*/
|
|
59
63
|
export function sanitizeMessagePreview(value: string): string {
|
|
60
|
-
|
|
61
|
-
const clamped =
|
|
62
|
-
stripped.length > MESSAGE_PREVIEW_MAX_LENGTH
|
|
63
|
-
? stripped.slice(0, MESSAGE_PREVIEW_MAX_LENGTH) + "…"
|
|
64
|
-
: stripped;
|
|
65
|
-
return clamped;
|
|
64
|
+
return sanitize(value, MESSAGE_PREVIEW_MAX_LENGTH);
|
|
66
65
|
}
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
* NotificationSignal -- the flexible input from producers.
|
|
3
3
|
* Uses free-form event names and structured attention hints that let the
|
|
4
4
|
* decision engine route contextually.
|
|
5
|
+
*
|
|
6
|
+
* All data shapes are defined as Zod schemas — types are derived via
|
|
7
|
+
* `z.infer` so runtime validation and compile-time types stay in sync.
|
|
5
8
|
*/
|
|
6
9
|
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
7
12
|
import type { ConversationCreateType } from "../memory/conversation-crud.js";
|
|
8
13
|
import type { GuardianQuestionPayload } from "./guardian-question-mode.js";
|
|
9
14
|
|
|
@@ -14,7 +19,11 @@ export const NOTIFICATION_SOURCE_CHANNELS = [
|
|
|
14
19
|
{ id: "vellum", description: "Vellum native client (macOS/iOS)" },
|
|
15
20
|
{ id: "phone", description: "Phone call pipeline" },
|
|
16
21
|
{ id: "telegram", description: "Telegram channel" },
|
|
22
|
+
{ id: "whatsapp", description: "WhatsApp channel" },
|
|
17
23
|
{ id: "slack", description: "Slack channel" },
|
|
24
|
+
{ id: "email", description: "Email channel" },
|
|
25
|
+
{ id: "platform", description: "Platform-managed channel" },
|
|
26
|
+
{ id: "a2a", description: "Agent-to-agent protocol channel" },
|
|
18
27
|
{ id: "scheduler", description: "Scheduled task runner (reminders, cron)" },
|
|
19
28
|
{ id: "watcher", description: "File/event watcher subsystem" },
|
|
20
29
|
] as const;
|
|
@@ -22,6 +31,18 @@ export const NOTIFICATION_SOURCE_CHANNELS = [
|
|
|
22
31
|
export type NotificationSourceChannel =
|
|
23
32
|
(typeof NOTIFICATION_SOURCE_CHANNELS)[number]["id"];
|
|
24
33
|
|
|
34
|
+
/** Typed tuple of all source channel IDs — usable with `z.enum()`. */
|
|
35
|
+
export const NOTIFICATION_SOURCE_CHANNEL_IDS = NOTIFICATION_SOURCE_CHANNELS.map(
|
|
36
|
+
(c) => c.id,
|
|
37
|
+
) as unknown as readonly [
|
|
38
|
+
NotificationSourceChannel,
|
|
39
|
+
...NotificationSourceChannel[],
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
export const NotificationSourceChannelSchema = z.enum(
|
|
43
|
+
NOTIFICATION_SOURCE_CHANNEL_IDS,
|
|
44
|
+
);
|
|
45
|
+
|
|
25
46
|
export function isNotificationSourceChannel(
|
|
26
47
|
value: unknown,
|
|
27
48
|
): value is NotificationSourceChannel {
|
|
@@ -114,15 +135,24 @@ export type NotificationSourceEventName =
|
|
|
114
135
|
|
|
115
136
|
// ── Attention hints & routing ──────────────────────────────────────────
|
|
116
137
|
|
|
117
|
-
export
|
|
118
|
-
|
|
119
|
-
urgency: "low" | "medium" | "high" | "critical";
|
|
120
|
-
deadlineAt?: number; // epoch ms
|
|
121
|
-
isAsyncBackground: boolean;
|
|
122
|
-
visibleInSourceNow: boolean;
|
|
123
|
-
}
|
|
138
|
+
export const UrgencySchema = z.enum(["low", "medium", "high", "critical"]);
|
|
139
|
+
export type Urgency = z.infer<typeof UrgencySchema>;
|
|
124
140
|
|
|
125
|
-
export
|
|
141
|
+
export const AttentionHintsSchema = z.object({
|
|
142
|
+
requiresAction: z.boolean(),
|
|
143
|
+
urgency: UrgencySchema,
|
|
144
|
+
deadlineAt: z.number().optional(),
|
|
145
|
+
isAsyncBackground: z.boolean(),
|
|
146
|
+
visibleInSourceNow: z.boolean(),
|
|
147
|
+
});
|
|
148
|
+
export type AttentionHints = z.infer<typeof AttentionHintsSchema>;
|
|
149
|
+
|
|
150
|
+
export const RoutingIntentSchema = z.enum([
|
|
151
|
+
"single_channel",
|
|
152
|
+
"multi_channel",
|
|
153
|
+
"all_channels",
|
|
154
|
+
]);
|
|
155
|
+
export type RoutingIntent = z.infer<typeof RoutingIntentSchema>;
|
|
126
156
|
|
|
127
157
|
// ── Typed context payloads ──────────────────────────────────────────────
|
|
128
158
|
|
|
@@ -140,42 +170,48 @@ export type RoutingIntent = "single_channel" | "multi_channel" | "all_channels";
|
|
|
140
170
|
* This is channel-agnostic by design — any channel's access request that
|
|
141
171
|
* resolves to a non-source-channel guardian gets the same treatment.
|
|
142
172
|
*/
|
|
143
|
-
export
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
export
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
sourceChannel: string;
|
|
152
|
-
conversationExternalId: string;
|
|
153
|
-
actorExternalId: string;
|
|
154
|
-
actorDisplayName: string | null;
|
|
155
|
-
actorUsername: string | null;
|
|
156
|
-
senderIdentifier: string;
|
|
157
|
-
guardianBindingChannel: string | null;
|
|
158
|
-
guardianResolutionSource: GuardianResolutionSource;
|
|
159
|
-
previousMemberStatus: string | null;
|
|
160
|
-
/** Preview of the requester's original message (first ~200 chars). */
|
|
161
|
-
messagePreview: string | null;
|
|
162
|
-
/** Slack-specific: user is from an external workspace (Slack Connect). */
|
|
163
|
-
isStranger?: boolean;
|
|
164
|
-
/** Slack-specific: user is a guest / restricted account. */
|
|
165
|
-
isRestricted?: boolean;
|
|
166
|
-
/** Slack message timestamp (e.g. "1234567890.123456") for permalink construction. */
|
|
167
|
-
messageTs?: string;
|
|
168
|
-
}
|
|
173
|
+
export const GuardianResolutionSourceSchema = z.enum([
|
|
174
|
+
"source-channel-contact",
|
|
175
|
+
"vellum-anchor",
|
|
176
|
+
"none",
|
|
177
|
+
]);
|
|
178
|
+
export type GuardianResolutionSource = z.infer<
|
|
179
|
+
typeof GuardianResolutionSourceSchema
|
|
180
|
+
>;
|
|
169
181
|
|
|
170
|
-
export
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
182
|
+
export const AccessRequestContextPayloadSchema = z.object({
|
|
183
|
+
requestId: z.string(),
|
|
184
|
+
requestCode: z.string(),
|
|
185
|
+
sourceChannel: z.string(),
|
|
186
|
+
conversationExternalId: z.string(),
|
|
187
|
+
actorExternalId: z.string(),
|
|
188
|
+
actorDisplayName: z.string().nullable(),
|
|
189
|
+
actorUsername: z.string().nullable(),
|
|
190
|
+
senderIdentifier: z.string(),
|
|
191
|
+
guardianBindingChannel: z.string().nullable(),
|
|
192
|
+
guardianResolutionSource: GuardianResolutionSourceSchema,
|
|
193
|
+
previousMemberStatus: z.string().nullable(),
|
|
194
|
+
messagePreview: z.string().nullable(),
|
|
195
|
+
isStranger: z.boolean().optional(),
|
|
196
|
+
isRestricted: z.boolean().optional(),
|
|
197
|
+
messageTs: z.string().optional(),
|
|
198
|
+
});
|
|
199
|
+
export type AccessRequestContextPayload = z.infer<
|
|
200
|
+
typeof AccessRequestContextPayloadSchema
|
|
201
|
+
>;
|
|
202
|
+
|
|
203
|
+
export const GuardianChannelActivationPayloadSchema = z.object({
|
|
204
|
+
verificationCode: z.string(),
|
|
205
|
+
sourceChannel: z.string(),
|
|
206
|
+
actorExternalId: z.string(),
|
|
207
|
+
actorDisplayName: z.string().nullable(),
|
|
208
|
+
actorUsername: z.string().nullable(),
|
|
209
|
+
sessionId: z.string(),
|
|
210
|
+
expiresAt: z.number(),
|
|
211
|
+
});
|
|
212
|
+
export type GuardianChannelActivationPayload = z.infer<
|
|
213
|
+
typeof GuardianChannelActivationPayloadSchema
|
|
214
|
+
>;
|
|
179
215
|
|
|
180
216
|
export interface NotificationEventContextPayloadMap {
|
|
181
217
|
"guardian.question": GuardianQuestionPayload;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core domain types for the unified notification system.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Data shapes are defined as Zod schemas — types derived via `z.infer`
|
|
5
|
+
* so runtime validation and compile-time types stay in sync.
|
|
6
|
+
*
|
|
7
|
+
* Behavioral interfaces (ChannelAdapter) remain as TypeScript interfaces.
|
|
6
8
|
*/
|
|
7
9
|
|
|
10
|
+
import { ApprovalUIMetadataSchema } from "@vellumai/gateway-client";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
8
13
|
import type { ChannelPolicies } from "../channels/config.js";
|
|
9
14
|
import type { ChannelId } from "../channels/types.js";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
15
|
+
import { AccessRequestPayloadSchema } from "./access-request-copy.js";
|
|
16
|
+
import { UrgencySchema } from "./signal.js";
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
19
|
* Derived from the channel policy registry: only channels whose
|
|
@@ -21,38 +26,39 @@ export type NotificationChannel = {
|
|
|
21
26
|
}[keyof ChannelPolicies] &
|
|
22
27
|
ChannelId;
|
|
23
28
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
messageId
|
|
55
|
-
}
|
|
29
|
+
export const NotificationDeliveryStatusSchema = z.enum([
|
|
30
|
+
"pending",
|
|
31
|
+
"sent",
|
|
32
|
+
"failed",
|
|
33
|
+
"skipped",
|
|
34
|
+
]);
|
|
35
|
+
export type NotificationDeliveryStatus = z.infer<
|
|
36
|
+
typeof NotificationDeliveryStatusSchema
|
|
37
|
+
>;
|
|
38
|
+
|
|
39
|
+
export const NotificationDeliveryResultSchema = z.object({
|
|
40
|
+
channel: z.string(),
|
|
41
|
+
destination: z.string(),
|
|
42
|
+
status: NotificationDeliveryStatusSchema,
|
|
43
|
+
errorCode: z.string().optional(),
|
|
44
|
+
errorMessage: z.string().optional(),
|
|
45
|
+
sentAt: z.number().optional(),
|
|
46
|
+
conversationId: z.string().optional(),
|
|
47
|
+
messageId: z.string().optional(),
|
|
48
|
+
conversationStrategy: z.string().optional(),
|
|
49
|
+
});
|
|
50
|
+
export type NotificationDeliveryResult = z.infer<
|
|
51
|
+
typeof NotificationDeliveryResultSchema
|
|
52
|
+
>;
|
|
53
|
+
|
|
54
|
+
// -- Channel adapter data shapes ----------------------------------------------
|
|
55
|
+
|
|
56
|
+
export const DeliveryResultSchema = z.object({
|
|
57
|
+
success: z.boolean(),
|
|
58
|
+
error: z.string().optional(),
|
|
59
|
+
messageId: z.string().optional(),
|
|
60
|
+
});
|
|
61
|
+
export type DeliveryResult = z.infer<typeof DeliveryResultSchema>;
|
|
56
62
|
|
|
57
63
|
/** Resolved destination for a specific channel. */
|
|
58
64
|
export interface ChannelDestination {
|
|
@@ -69,52 +75,44 @@ export interface ChannelDestination {
|
|
|
69
75
|
* conversations keyed by (sourceChannel, externalChatId).
|
|
70
76
|
*/
|
|
71
77
|
export interface DestinationBindingContext {
|
|
72
|
-
/** The channel this binding belongs to (e.g. "telegram", "slack"). */
|
|
73
78
|
sourceChannel: NotificationChannel;
|
|
74
|
-
/** The channel-specific chat/conversation identifier (e.g. Telegram chat ID, phone number). */
|
|
75
79
|
externalChatId: string;
|
|
76
|
-
/** Optional external user identifier within the chat. */
|
|
77
80
|
externalUserId?: string;
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
urgency:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
approvalContext?: ApprovalUIMetadata;
|
|
106
|
-
}
|
|
83
|
+
// -- Rendered copy & delivery payload -----------------------------------------
|
|
84
|
+
|
|
85
|
+
export const RenderedChannelCopySchema = z.object({
|
|
86
|
+
title: z.string(),
|
|
87
|
+
body: z.string(),
|
|
88
|
+
deliveryText: z.string().optional(),
|
|
89
|
+
conversationTitle: z.string().optional(),
|
|
90
|
+
conversationSeedMessage: z.string().optional(),
|
|
91
|
+
seedContentBlocks: z.array(z.unknown()).optional(),
|
|
92
|
+
});
|
|
93
|
+
export type RenderedChannelCopy = z.infer<typeof RenderedChannelCopySchema>;
|
|
94
|
+
|
|
95
|
+
export const ChannelDeliveryPayloadSchema = z.object({
|
|
96
|
+
deliveryId: z.string().optional(),
|
|
97
|
+
sourceEventName: z.string(),
|
|
98
|
+
copy: RenderedChannelCopySchema,
|
|
99
|
+
deepLinkTarget: z.record(z.string(), z.unknown()).optional(),
|
|
100
|
+
contextPayload: z.record(z.string(), z.unknown()).optional(),
|
|
101
|
+
urgency: UrgencySchema,
|
|
102
|
+
approvalContext: ApprovalUIMetadataSchema.optional(),
|
|
103
|
+
accessRequestContext: AccessRequestPayloadSchema.optional(),
|
|
104
|
+
});
|
|
105
|
+
export type ChannelDeliveryPayload = z.infer<
|
|
106
|
+
typeof ChannelDeliveryPayloadSchema
|
|
107
|
+
>;
|
|
107
108
|
|
|
108
|
-
/**
|
|
109
|
-
* Patch supplied when an already-delivered notification is edited.
|
|
110
|
-
* Adapters only need to act on `title` and `body` — feed-only fields
|
|
111
|
-
* like `urgency` and `status` are handled by the home-feed patch.
|
|
112
|
-
*/
|
|
113
109
|
export interface ChannelUpdatePayload {
|
|
114
110
|
title?: string;
|
|
115
111
|
body?: string;
|
|
116
112
|
}
|
|
117
113
|
|
|
114
|
+
// -- Channel adapter interface ------------------------------------------------
|
|
115
|
+
|
|
118
116
|
/** Interface that each channel adapter must implement. */
|
|
119
117
|
export interface ChannelAdapter {
|
|
120
118
|
channel: NotificationChannel;
|
|
@@ -122,77 +120,57 @@ export interface ChannelAdapter {
|
|
|
122
120
|
payload: ChannelDeliveryPayload,
|
|
123
121
|
destination: ChannelDestination,
|
|
124
122
|
): Promise<DeliveryResult>;
|
|
125
|
-
/**
|
|
126
|
-
* Optional: edit a previously-sent message in place. Channels that
|
|
127
|
-
* cannot edit (push, email, SMS) omit this and the router treats
|
|
128
|
-
* them as `"unsupported"`. Adapters that implement it use
|
|
129
|
-
* `delivery.messageId` (captured at send time) as the channel-native
|
|
130
|
-
* handle for the in-place update.
|
|
131
|
-
*/
|
|
132
123
|
update?(
|
|
133
124
|
delivery: ChannelUpdateContext,
|
|
134
125
|
patch: ChannelUpdatePayload,
|
|
135
126
|
): Promise<DeliveryResult>;
|
|
136
127
|
}
|
|
137
128
|
|
|
138
|
-
/** Per-delivery state an adapter needs to update a previously-sent message. */
|
|
139
129
|
export interface ChannelUpdateContext {
|
|
140
|
-
/** notification_deliveries.id */
|
|
141
130
|
deliveryId: string;
|
|
142
|
-
/** Channel-native destination (e.g. Slack chat id). */
|
|
143
131
|
destination: string;
|
|
144
|
-
/** Channel-native message identifier captured at send time. */
|
|
145
132
|
messageId: string | null;
|
|
146
133
|
}
|
|
147
134
|
|
|
148
|
-
// -- Decision engine output ---------------------------------------------------
|
|
149
|
-
|
|
150
|
-
/** Rendered notification copy for a single channel. */
|
|
151
|
-
export interface RenderedChannelCopy {
|
|
152
|
-
title: string;
|
|
153
|
-
body: string;
|
|
154
|
-
/** Channel-native delivery text (e.g. Telegram chat message body). */
|
|
155
|
-
deliveryText?: string;
|
|
156
|
-
conversationTitle?: string;
|
|
157
|
-
conversationSeedMessage?: string;
|
|
158
|
-
/**
|
|
159
|
-
* Structured content blocks for the seed message. When present,
|
|
160
|
-
* conversation pairing stores `JSON.stringify(seedContentBlocks)` as the
|
|
161
|
-
* message content instead of the plain-text seed, enabling Surface
|
|
162
|
-
* rendering in the web/macOS/iOS apps.
|
|
163
|
-
*
|
|
164
|
-
* Typically includes a `ui_surface` block (rendered as an interactive
|
|
165
|
-
* card) followed by a `text` block (plain-text fallback for search,
|
|
166
|
-
* backward-compatible clients, and CLI display).
|
|
167
|
-
*/
|
|
168
|
-
seedContentBlocks?: unknown[];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
135
|
// -- Conversation action types ------------------------------------------------
|
|
172
136
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
137
|
+
export const ConversationActionSchema = z.discriminatedUnion("action", [
|
|
138
|
+
z.object({ action: z.literal("start_new") }),
|
|
139
|
+
z.object({
|
|
140
|
+
action: z.literal("reuse_existing"),
|
|
141
|
+
conversationId: z.string(),
|
|
142
|
+
}),
|
|
143
|
+
]);
|
|
144
|
+
export type ConversationAction = z.infer<typeof ConversationActionSchema>;
|
|
177
145
|
|
|
178
|
-
|
|
179
|
-
export interface ConversationActionReuseExisting {
|
|
180
|
-
action: "reuse_existing";
|
|
181
|
-
conversationId: string;
|
|
182
|
-
}
|
|
146
|
+
// -- Decision engine output ---------------------------------------------------
|
|
183
147
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
148
|
+
export const NotificationDecisionSchema = z.object({
|
|
149
|
+
shouldNotify: z.boolean(),
|
|
150
|
+
selectedChannels: z.array(z.string()),
|
|
151
|
+
reasoningSummary: z.string(),
|
|
152
|
+
renderedCopy: z.record(z.string(), RenderedChannelCopySchema),
|
|
153
|
+
conversationActions: z
|
|
154
|
+
.record(z.string(), ConversationActionSchema)
|
|
155
|
+
.optional(),
|
|
156
|
+
deepLinkTarget: z.record(z.string(), z.unknown()).optional(),
|
|
157
|
+
dedupeKey: z.string(),
|
|
158
|
+
confidence: z.number(),
|
|
159
|
+
fallbackUsed: z.boolean(),
|
|
160
|
+
persistedDecisionId: z.string().optional(),
|
|
161
|
+
});
|
|
188
162
|
|
|
189
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Decision engine output. `selectedChannels` and `renderedCopy` are keyed
|
|
165
|
+
* by `NotificationChannel` — narrower than the Zod schema's `string` since
|
|
166
|
+
* `NotificationChannel` is a computed type derived from the channel config
|
|
167
|
+
* registry and cannot be expressed as a Zod enum.
|
|
168
|
+
*/
|
|
190
169
|
export interface NotificationDecision {
|
|
191
170
|
shouldNotify: boolean;
|
|
192
171
|
selectedChannels: NotificationChannel[];
|
|
193
172
|
reasoningSummary: string;
|
|
194
173
|
renderedCopy: Partial<Record<NotificationChannel, RenderedChannelCopy>>;
|
|
195
|
-
/** Per-channel conversation actions decided by the model. Absent channels default to start_new. */
|
|
196
174
|
conversationActions?: Partial<
|
|
197
175
|
Record<NotificationChannel, ConversationAction>
|
|
198
176
|
>;
|
|
@@ -200,6 +178,5 @@ export interface NotificationDecision {
|
|
|
200
178
|
dedupeKey: string;
|
|
201
179
|
confidence: number;
|
|
202
180
|
fallbackUsed: boolean;
|
|
203
|
-
/** UUID of the persisted decision row (set after persistence in the decision engine). */
|
|
204
181
|
persistedDecisionId?: string;
|
|
205
182
|
}
|
package/src/oauth/AGENTS.md
CHANGED
|
@@ -29,34 +29,15 @@ Then add the key to `ServicesSchema`:
|
|
|
29
29
|
|
|
30
30
|
The key here **must** match the `managedServiceConfigKey` in `seed-providers.ts`. The cross-repo invariant test in `__tests__/seed-providers-managed.test.ts` will fail if they drift.
|
|
31
31
|
|
|
32
|
-
### 3. _(managed only)_ Enable by default during onboarding
|
|
32
|
+
### 3. _(managed only)_ Enable by default during onboarding
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Managed-sign-in users should get the integration pre-enabled by setting `services.acme-oauth.mode` to `"managed"` in the client's onboarding config defaults.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
configValues["services.acme-oauth.mode"] = "managed"
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 4. Add a cached logo — `clients/shared/Resources/IntegrationLogos/`
|
|
41
|
-
|
|
42
|
-
Drop a **vector PDF** named `{provider_key}.pdf` (e.g. `acme.pdf`) into the `IntegrationLogos/` directory. The file is automatically bundled via `.copy()` in `clients/Package.swift` and looked up at runtime by `IntegrationLogoBundle` using the provider key — no code changes needed.
|
|
43
|
-
|
|
44
|
-
Most existing logos come from [Simple Icons](https://simpleicons.org) (CC0-licensed). To get a PDF from Simple Icons:
|
|
45
|
-
|
|
46
|
-
1. Find the icon slug on https://simpleicons.org (e.g. `slack`, `linear`).
|
|
47
|
-
2. Download the SVG: `curl -o acme.svg https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/acme.svg`
|
|
48
|
-
3. Convert to PDF using `rsvg-convert` (same tool used by `clients/scripts/sync-lucide-icons.sh`):
|
|
49
|
-
```bash
|
|
50
|
-
# Install if needed: brew install librsvg
|
|
51
|
-
rsvg-convert -f pdf -o clients/shared/Resources/IntegrationLogos/acme.pdf acme.svg
|
|
52
|
-
```
|
|
53
|
-
4. Add the provider key to `clients/shared/Resources/integration-logos-manifest.json`.
|
|
54
|
-
|
|
55
|
-
If the service is not on Simple Icons, source or create an SVG and convert it the same way. The result must be a true vector PDF (not a rasterized image wrapped in PDF) so it scales cleanly.
|
|
36
|
+
### 4. Set the logo URL — `seed-providers.ts`
|
|
56
37
|
|
|
57
|
-
The `logoUrl` field in `seed-providers.ts`
|
|
38
|
+
The `logoUrl` field in `seed-providers.ts` is the source of truth for a provider's logo. Most providers use a [Simple Icons](https://simpleicons.org) (CC0-licensed) CDN URL like `https://cdn.simpleicons.org/acme`. The web client resolves logos from this field (see `clients/web/src/components/integrations/integration-icon.tsx`) and falls back to an initials avatar.
|
|
58
39
|
|
|
59
|
-
For brands Simple Icons doesn't host (e.g. Salesforce, which Simple Icons removed for trademark reasons), use the
|
|
40
|
+
For brands Simple Icons doesn't host (e.g. Salesforce, which Simple Icons removed for trademark reasons), use the `glincker/thesvg` source via jsDelivr — `https://cdn.jsdelivr.net/gh/glincker/thesvg@main/public/icons/<key>/default.svg`. The recognised `logoUrl` prefixes are enforced by `oauth-provider-seed-logos.test.ts`; if you need a third source, extend that allowlist.
|
|
60
41
|
|
|
61
42
|
### 5. Secret patterns (if applicable) — `../security/secret-patterns.ts`
|
|
62
43
|
|