@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
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
|
|
10
|
-
import { buildApprovalCardBlocks } from "./approval-card-builder.js";
|
|
11
10
|
import {
|
|
12
11
|
nonEmpty,
|
|
13
12
|
sanitizeIdentityField,
|
|
@@ -312,74 +311,88 @@ export function buildAccessRequestContractText(
|
|
|
312
311
|
return lines.join("\n");
|
|
313
312
|
}
|
|
314
313
|
|
|
315
|
-
// ──
|
|
314
|
+
// ── Card view model ─────────────────────────────────────────────────────────
|
|
316
315
|
|
|
317
316
|
/**
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
317
|
+
* Display-ready projection of an access request, shared by every renderer
|
|
318
|
+
* (the Vellum Surface card and the Slack Card block). It carries the
|
|
319
|
+
* sanitized, pre-computed facts each renderer needs — identity sanitizing,
|
|
320
|
+
* warnings, permalink, DM detection, preview sanitizing — so that projection
|
|
321
|
+
* lives in exactly one place. Renderers lay these facts out in their
|
|
322
|
+
* channel-native shape without re-deriving them.
|
|
323
323
|
*/
|
|
324
|
-
export
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
324
|
+
export interface AccessRequestCardView {
|
|
325
|
+
/** Sanitized display name (actorDisplayName ?? senderIdentifier, else "Someone"). */
|
|
326
|
+
displayName: string;
|
|
327
|
+
/** Sanitized username, without the leading `@`. */
|
|
328
|
+
username: string | undefined;
|
|
329
|
+
/** Sanitized external ID. */
|
|
330
|
+
externalId: string | undefined;
|
|
331
|
+
sourceChannel: string | undefined;
|
|
332
|
+
conversationExternalId: string | undefined;
|
|
333
|
+
/** Whether the source Slack conversation is a DM. */
|
|
334
|
+
isSlackDm: boolean;
|
|
335
|
+
/** Slack permalink — present only for a slack source with conversation + ts. */
|
|
336
|
+
messagePermalink: string | undefined;
|
|
337
|
+
/** Sanitized message preview, or undefined when blank after sanitizing. */
|
|
338
|
+
messagePreview: string | undefined;
|
|
339
|
+
/** Human-readable trust/security warnings. */
|
|
340
|
+
warnings: string[];
|
|
341
|
+
guardianResolutionSource: string | undefined;
|
|
342
|
+
requestId: string | undefined;
|
|
343
|
+
}
|
|
328
344
|
|
|
345
|
+
/**
|
|
346
|
+
* Project a parsed access-request payload into display-ready card facts.
|
|
347
|
+
*
|
|
348
|
+
* The payload is parsed once upstream — the broadcaster resolves
|
|
349
|
+
* `accessRequestContext`, and the Surface seed path parses the raw payload —
|
|
350
|
+
* so this takes the parsed payload rather than re-parsing it.
|
|
351
|
+
*/
|
|
352
|
+
export function buildAccessRequestCardView(
|
|
353
|
+
p: ParsedAccessRequestPayload,
|
|
354
|
+
): AccessRequestCardView {
|
|
329
355
|
const rawName = nonEmpty(p.actorDisplayName) ?? nonEmpty(p.senderIdentifier);
|
|
330
356
|
const displayName = rawName ? sanitizeIdentityField(rawName) : "Someone";
|
|
331
357
|
|
|
332
|
-
const
|
|
358
|
+
const rawUsername = nonEmpty(p.actorUsername);
|
|
359
|
+
const username = rawUsername ? sanitizeIdentityField(rawUsername) : undefined;
|
|
333
360
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
});
|
|
339
|
-
}
|
|
361
|
+
const rawExternalId = nonEmpty(p.actorExternalId);
|
|
362
|
+
const externalId = rawExternalId
|
|
363
|
+
? sanitizeIdentityField(rawExternalId)
|
|
364
|
+
: undefined;
|
|
340
365
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
label: "Source",
|
|
345
|
-
value: isDm
|
|
346
|
-
? "Slack — Direct message"
|
|
347
|
-
: `Slack — #${p.conversationExternalId}`,
|
|
348
|
-
});
|
|
349
|
-
} else if (p.sourceChannel) {
|
|
350
|
-
metadata.push({ label: "Source", value: p.sourceChannel });
|
|
351
|
-
}
|
|
366
|
+
const sourceChannel = nonEmpty(p.sourceChannel);
|
|
367
|
+
const conversationExternalId = nonEmpty(p.conversationExternalId);
|
|
368
|
+
const messageTs = nonEmpty(p.messageTs);
|
|
352
369
|
|
|
353
|
-
const
|
|
354
|
-
|
|
370
|
+
const isSlackDm =
|
|
371
|
+
sourceChannel === "slack" && conversationExternalId != null
|
|
372
|
+
? isSlackDmConversation(conversationExternalId)
|
|
373
|
+
: false;
|
|
355
374
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
p.messageTs,
|
|
366
|
-
);
|
|
367
|
-
bodyParts.push(`[View message](${permalink})`);
|
|
368
|
-
}
|
|
375
|
+
const messagePermalink =
|
|
376
|
+
sourceChannel === "slack" && conversationExternalId && messageTs
|
|
377
|
+
? buildSlackMessagePermalink(conversationExternalId, messageTs)
|
|
378
|
+
: undefined;
|
|
379
|
+
|
|
380
|
+
const rawPreview = nonEmpty(p.messagePreview);
|
|
381
|
+
const messagePreview = rawPreview
|
|
382
|
+
? sanitizeMessagePreview(rawPreview) || undefined
|
|
383
|
+
: undefined;
|
|
369
384
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
fallbackText: buildAccessRequestContractText(payload),
|
|
384
|
-
});
|
|
385
|
+
return {
|
|
386
|
+
displayName,
|
|
387
|
+
username,
|
|
388
|
+
externalId,
|
|
389
|
+
sourceChannel,
|
|
390
|
+
conversationExternalId,
|
|
391
|
+
isSlackDm,
|
|
392
|
+
messagePermalink,
|
|
393
|
+
messagePreview,
|
|
394
|
+
warnings: buildAccessRequestWarnings(p),
|
|
395
|
+
guardianResolutionSource: nonEmpty(p.guardianResolutionSource),
|
|
396
|
+
requestId: nonEmpty(p.requestId),
|
|
397
|
+
};
|
|
385
398
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared adapter utilities — functions used by multiple channel adapters.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isConversationSeedSane } from "../conversation-seed-composer.js";
|
|
6
|
+
import { nonEmpty } from "../notification-utils.js";
|
|
7
|
+
import type { ChannelDeliveryPayload } from "../types.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the primary message text for a notification delivery.
|
|
11
|
+
*
|
|
12
|
+
* Cascade: deliveryText → conversationSeedMessage → body → title → event name.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveMessageText(payload: ChannelDeliveryPayload): string {
|
|
15
|
+
const deliveryText = nonEmpty(payload.copy.deliveryText);
|
|
16
|
+
if (deliveryText) return deliveryText;
|
|
17
|
+
|
|
18
|
+
if (isConversationSeedSane(payload.copy.conversationSeedMessage)) {
|
|
19
|
+
return payload.copy.conversationSeedMessage.trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const body = nonEmpty(payload.copy.body);
|
|
23
|
+
if (body) return body;
|
|
24
|
+
|
|
25
|
+
const title = nonEmpty(payload.copy.title);
|
|
26
|
+
if (title) return title;
|
|
27
|
+
|
|
28
|
+
return payload.sourceEventName.replace(/[._]/g, " ");
|
|
29
|
+
}
|
|
@@ -16,19 +16,11 @@ import { sendSlackReply } from "../../messaging/providers/slack/send.js";
|
|
|
16
16
|
import type { ApprovalUIMetadata } from "../../runtime/channel-approval-types.js";
|
|
17
17
|
import { getLogger } from "../../util/logger.js";
|
|
18
18
|
import {
|
|
19
|
+
type AccessRequestCardView,
|
|
20
|
+
buildAccessRequestCardView,
|
|
19
21
|
buildAccessRequestInviteDirective,
|
|
20
|
-
buildAccessRequestWarnings,
|
|
21
|
-
buildSlackMessagePermalink,
|
|
22
|
-
isSlackDmConversation,
|
|
23
|
-
parseAccessRequestPayload,
|
|
24
|
-
type ParsedAccessRequestPayload,
|
|
25
22
|
} from "../access-request-copy.js";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
nonEmpty,
|
|
29
|
-
sanitizeIdentityField,
|
|
30
|
-
sanitizeMessagePreview,
|
|
31
|
-
} from "../notification-utils.js";
|
|
23
|
+
import { truncate } from "../notification-utils.js";
|
|
32
24
|
import type {
|
|
33
25
|
ChannelAdapter,
|
|
34
26
|
ChannelDeliveryPayload,
|
|
@@ -38,36 +30,10 @@ import type {
|
|
|
38
30
|
DeliveryResult,
|
|
39
31
|
NotificationChannel,
|
|
40
32
|
} from "../types.js";
|
|
33
|
+
import { resolveMessageText } from "./shared.js";
|
|
41
34
|
|
|
42
35
|
const log = getLogger("notif-adapter-slack");
|
|
43
36
|
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Text resolution
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
function resolveSlackMessageText(payload: ChannelDeliveryPayload): string {
|
|
49
|
-
const deliveryText = nonEmpty(payload.copy.deliveryText);
|
|
50
|
-
if (deliveryText) return deliveryText;
|
|
51
|
-
|
|
52
|
-
if (isConversationSeedSane(payload.copy.conversationSeedMessage)) {
|
|
53
|
-
return payload.copy.conversationSeedMessage.trim();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const body = nonEmpty(payload.copy.body);
|
|
57
|
-
if (body) return body;
|
|
58
|
-
|
|
59
|
-
const title = nonEmpty(payload.copy.title);
|
|
60
|
-
if (title) return title;
|
|
61
|
-
|
|
62
|
-
return payload.sourceEventName.replace(/[._]/g, " ");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Truncate to `maxLength`, appending "…" when exceeded. */
|
|
66
|
-
function truncate(text: string, maxLength: number): string {
|
|
67
|
-
if (text.length <= maxLength) return text;
|
|
68
|
-
return text.slice(0, maxLength - 1) + "…";
|
|
69
|
-
}
|
|
70
|
-
|
|
71
37
|
// ---------------------------------------------------------------------------
|
|
72
38
|
// Slack Card block builders for approval notifications
|
|
73
39
|
// ---------------------------------------------------------------------------
|
|
@@ -88,57 +54,48 @@ function buildCardActions(approval: ApprovalUIMetadata): unknown[] {
|
|
|
88
54
|
// ---------------------------------------------------------------------------
|
|
89
55
|
|
|
90
56
|
/** Concise requester identity for the card subtitle (≤150 chars). */
|
|
91
|
-
function buildAccessRequestSubtitle(
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const username = nonEmpty(p.actorUsername);
|
|
97
|
-
if (username) {
|
|
98
|
-
const safe = sanitizeIdentityField(username);
|
|
99
|
-
if (safe !== displayName) parts.push(`(@${safe})`);
|
|
57
|
+
function buildAccessRequestSubtitle(view: AccessRequestCardView): string {
|
|
58
|
+
const parts = [view.displayName];
|
|
59
|
+
|
|
60
|
+
if (view.username && view.username !== view.displayName) {
|
|
61
|
+
parts.push(`(@${view.username})`);
|
|
100
62
|
}
|
|
101
63
|
|
|
102
|
-
if (
|
|
64
|
+
if (view.sourceChannel) parts.push(`via ${view.sourceChannel}`);
|
|
103
65
|
|
|
104
66
|
return truncate(parts.join(" "), 150);
|
|
105
67
|
}
|
|
106
68
|
|
|
107
69
|
/** Card body: message preview when available, otherwise a default label. */
|
|
108
|
-
function buildAccessRequestBody(
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const trimmed = truncate(sanitized, 200 - 6);
|
|
115
|
-
return `> _"${trimmed}"_`;
|
|
116
|
-
}
|
|
70
|
+
function buildAccessRequestBody(view: AccessRequestCardView): string {
|
|
71
|
+
if (view.messagePreview) {
|
|
72
|
+
// Truncate content before wrapping so formatting chars stay balanced.
|
|
73
|
+
// Wrapper `> _"..."_` is 6 chars; reserve space for them.
|
|
74
|
+
const trimmed = truncate(view.messagePreview, 200 - 6);
|
|
75
|
+
return `> _"${trimmed}"_`;
|
|
117
76
|
}
|
|
118
77
|
return "Requesting access to the assistant";
|
|
119
78
|
}
|
|
120
79
|
|
|
121
80
|
/** Source-channel context block with Slack permalink when available. */
|
|
122
81
|
function buildSourceContextBlock(
|
|
123
|
-
|
|
82
|
+
view: AccessRequestCardView,
|
|
124
83
|
): unknown | undefined {
|
|
125
|
-
if (
|
|
84
|
+
if (view.sourceChannel !== "slack" || !view.conversationExternalId) {
|
|
126
85
|
return undefined;
|
|
127
86
|
}
|
|
128
87
|
|
|
129
|
-
const permalink =
|
|
130
|
-
? buildSlackMessagePermalink(p.conversationExternalId, p.messageTs)
|
|
131
|
-
: undefined;
|
|
88
|
+
const permalink = view.messagePermalink;
|
|
132
89
|
|
|
133
90
|
let sourceText: string;
|
|
134
|
-
if (
|
|
91
|
+
if (view.isSlackDm) {
|
|
135
92
|
sourceText = permalink
|
|
136
93
|
? `Source: Slack — Direct message · <${permalink}|View message>`
|
|
137
94
|
: "Source: Slack — Direct message";
|
|
138
95
|
} else {
|
|
139
96
|
sourceText = permalink
|
|
140
|
-
? `Source: Slack — <#${
|
|
141
|
-
: `Source: Slack — <#${
|
|
97
|
+
? `Source: Slack — <#${view.conversationExternalId}> · <${permalink}|View message>`
|
|
98
|
+
: `Source: Slack — <#${view.conversationExternalId}>`;
|
|
142
99
|
}
|
|
143
100
|
|
|
144
101
|
return {
|
|
@@ -149,27 +106,12 @@ function buildSourceContextBlock(
|
|
|
149
106
|
|
|
150
107
|
/** Stable requester identifier context block (external ID when it adds info). */
|
|
151
108
|
function buildRequesterIdBlock(
|
|
152
|
-
|
|
109
|
+
view: AccessRequestCardView,
|
|
153
110
|
): unknown | undefined {
|
|
154
|
-
const safeExternalId =
|
|
155
|
-
p.actorExternalId ? sanitizeIdentityField(p.actorExternalId) : undefined,
|
|
156
|
-
);
|
|
111
|
+
const safeExternalId = view.externalId;
|
|
157
112
|
if (!safeExternalId) return undefined;
|
|
158
113
|
|
|
159
|
-
|
|
160
|
-
p.actorDisplayName
|
|
161
|
-
? sanitizeIdentityField(p.actorDisplayName)
|
|
162
|
-
: p.senderIdentifier
|
|
163
|
-
? sanitizeIdentityField(p.senderIdentifier)
|
|
164
|
-
: undefined,
|
|
165
|
-
);
|
|
166
|
-
const displayedUsername = nonEmpty(
|
|
167
|
-
p.actorUsername ? sanitizeIdentityField(p.actorUsername) : undefined,
|
|
168
|
-
);
|
|
169
|
-
if (
|
|
170
|
-
safeExternalId === displayedName ||
|
|
171
|
-
safeExternalId === displayedUsername
|
|
172
|
-
) {
|
|
114
|
+
if (safeExternalId === view.displayName || safeExternalId === view.username) {
|
|
173
115
|
return undefined;
|
|
174
116
|
}
|
|
175
117
|
|
|
@@ -183,7 +125,8 @@ function buildRequesterIdBlock(
|
|
|
183
125
|
* Build Slack blocks for an access request using a native Card block.
|
|
184
126
|
*
|
|
185
127
|
* Layout:
|
|
186
|
-
* Card — title + subtitle (identity) + body (preview) + actions
|
|
128
|
+
* Card — title + subtitle (identity) + body (preview) + actions
|
|
129
|
+
* Context — security warnings (revoked/restricted/stranger), when present
|
|
187
130
|
* Context — source permalink (when the request is from Slack)
|
|
188
131
|
* Context — stable requester ID (when it adds info beyond subtitle)
|
|
189
132
|
* Context — invite directive
|
|
@@ -193,32 +136,42 @@ function buildAccessRequestCardBlocks(
|
|
|
193
136
|
payload: ChannelDeliveryPayload,
|
|
194
137
|
): unknown[] {
|
|
195
138
|
const approval = payload.approvalContext!;
|
|
196
|
-
const
|
|
139
|
+
const view = buildAccessRequestCardView(payload.accessRequestContext!);
|
|
197
140
|
const blocks: unknown[] = [];
|
|
198
141
|
|
|
199
|
-
const subtitle = buildAccessRequestSubtitle(
|
|
200
|
-
const body = buildAccessRequestBody(
|
|
142
|
+
const subtitle = buildAccessRequestSubtitle(view);
|
|
143
|
+
const body = buildAccessRequestBody(view);
|
|
201
144
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
? truncate(warnings.map((w) => `:warning: ${w}`).join(" · "), 200)
|
|
145
|
+
const warningsText =
|
|
146
|
+
view.warnings.length > 0
|
|
147
|
+
? truncate(view.warnings.map((w) => `:warning: ${w}`).join(" · "), 200)
|
|
206
148
|
: undefined;
|
|
207
149
|
|
|
208
150
|
const card: Record<string, unknown> = {
|
|
209
151
|
type: "card",
|
|
210
|
-
title: { type: "
|
|
152
|
+
title: { type: "mrkdwn", text: "Access Request" },
|
|
211
153
|
subtitle: { type: "mrkdwn", text: subtitle },
|
|
212
154
|
body: { type: "mrkdwn", text: body },
|
|
213
155
|
actions: buildCardActions(approval),
|
|
214
156
|
};
|
|
215
|
-
if (subtext) card.subtext = { type: "mrkdwn", text: subtext };
|
|
216
157
|
blocks.push(card);
|
|
217
158
|
|
|
218
|
-
|
|
159
|
+
// Security warnings (revoked / restricted / stranger) render in a context
|
|
160
|
+
// block under the card. Slack's card block schema has no field for them
|
|
161
|
+
// (https://docs.slack.dev/reference/block-kit/blocks/card-block) and Slack
|
|
162
|
+
// silently drops unknown card fields, so a dedicated block is needed to
|
|
163
|
+
// surface them to the guardian.
|
|
164
|
+
if (warningsText) {
|
|
165
|
+
blocks.push({
|
|
166
|
+
type: "context",
|
|
167
|
+
elements: [{ type: "mrkdwn", text: warningsText }],
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const sourceContext = buildSourceContextBlock(view);
|
|
219
172
|
if (sourceContext) blocks.push(sourceContext);
|
|
220
173
|
|
|
221
|
-
const idBlock = buildRequesterIdBlock(
|
|
174
|
+
const idBlock = buildRequesterIdBlock(view);
|
|
222
175
|
if (idBlock) blocks.push(idBlock);
|
|
223
176
|
|
|
224
177
|
blocks.push({
|
|
@@ -227,16 +180,16 @@ function buildAccessRequestCardBlocks(
|
|
|
227
180
|
});
|
|
228
181
|
|
|
229
182
|
if (
|
|
230
|
-
(
|
|
231
|
-
|
|
232
|
-
|
|
183
|
+
(view.guardianResolutionSource === "vellum-anchor" ||
|
|
184
|
+
view.guardianResolutionSource === "none") &&
|
|
185
|
+
view.sourceChannel
|
|
233
186
|
) {
|
|
234
187
|
blocks.push({
|
|
235
188
|
type: "context",
|
|
236
189
|
elements: [
|
|
237
190
|
{
|
|
238
191
|
type: "mrkdwn",
|
|
239
|
-
text: `_You haven't verified your identity on ${
|
|
192
|
+
text: `_You haven't verified your identity on ${view.sourceChannel} yet. If this was you trying to message your assistant, say "help me verify as guardian on ${view.sourceChannel}" to set up direct access._`,
|
|
240
193
|
},
|
|
241
194
|
],
|
|
242
195
|
});
|
|
@@ -276,7 +229,7 @@ function buildToolApprovalCardBlocks(
|
|
|
276
229
|
const card: Record<string, unknown> = {
|
|
277
230
|
type: "card",
|
|
278
231
|
title: {
|
|
279
|
-
type: "
|
|
232
|
+
type: "mrkdwn",
|
|
280
233
|
text: details ? "Tool Approval" : "Approval Request",
|
|
281
234
|
},
|
|
282
235
|
body: {
|
|
@@ -307,14 +260,16 @@ function buildToolApprovalCardBlocks(
|
|
|
307
260
|
/**
|
|
308
261
|
* Build Slack blocks for any notification carrying approval context.
|
|
309
262
|
* Dispatches to the appropriate card builder based on source event type.
|
|
263
|
+
*
|
|
264
|
+
* Exported for characterization tests of the approval-card block output.
|
|
310
265
|
*/
|
|
311
|
-
function buildApprovalNotificationBlocks(
|
|
266
|
+
export function buildApprovalNotificationBlocks(
|
|
312
267
|
payload: ChannelDeliveryPayload,
|
|
313
268
|
messageText: string,
|
|
314
269
|
): unknown[] {
|
|
315
270
|
if (
|
|
316
271
|
payload.sourceEventName === "ingress.access_request" &&
|
|
317
|
-
payload.
|
|
272
|
+
payload.accessRequestContext != null
|
|
318
273
|
) {
|
|
319
274
|
return buildAccessRequestCardBlocks(payload);
|
|
320
275
|
}
|
|
@@ -345,7 +300,7 @@ export class SlackAdapter implements ChannelAdapter {
|
|
|
345
300
|
};
|
|
346
301
|
}
|
|
347
302
|
|
|
348
|
-
const messageText =
|
|
303
|
+
const messageText = resolveMessageText(payload);
|
|
349
304
|
|
|
350
305
|
try {
|
|
351
306
|
const result = payload.approvalContext
|
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
import { sendTelegramReply } from "../../messaging/providers/telegram-bot/send.js";
|
|
12
12
|
import { ConfigError } from "../../util/errors.js";
|
|
13
13
|
import { getLogger } from "../../util/logger.js";
|
|
14
|
-
import { isConversationSeedSane } from "../conversation-seed-composer.js";
|
|
15
|
-
import { nonEmpty } from "../notification-utils.js";
|
|
16
14
|
import type {
|
|
17
15
|
ChannelAdapter,
|
|
18
16
|
ChannelDeliveryPayload,
|
|
@@ -20,26 +18,10 @@ import type {
|
|
|
20
18
|
DeliveryResult,
|
|
21
19
|
NotificationChannel,
|
|
22
20
|
} from "../types.js";
|
|
21
|
+
import { resolveMessageText } from "./shared.js";
|
|
23
22
|
|
|
24
23
|
const log = getLogger("notif-adapter-telegram");
|
|
25
24
|
|
|
26
|
-
function resolveTelegramMessageText(payload: ChannelDeliveryPayload): string {
|
|
27
|
-
const deliveryText = nonEmpty(payload.copy.deliveryText);
|
|
28
|
-
if (deliveryText) return deliveryText;
|
|
29
|
-
|
|
30
|
-
if (isConversationSeedSane(payload.copy.conversationSeedMessage)) {
|
|
31
|
-
return payload.copy.conversationSeedMessage.trim();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const body = nonEmpty(payload.copy.body);
|
|
35
|
-
if (body) return body;
|
|
36
|
-
|
|
37
|
-
const title = nonEmpty(payload.copy.title);
|
|
38
|
-
if (title) return title;
|
|
39
|
-
|
|
40
|
-
return payload.sourceEventName.replace(/[._]/g, " ");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
25
|
export class TelegramAdapter implements ChannelAdapter {
|
|
44
26
|
readonly channel: NotificationChannel = "telegram";
|
|
45
27
|
|
|
@@ -59,7 +41,7 @@ export class TelegramAdapter implements ChannelAdapter {
|
|
|
59
41
|
};
|
|
60
42
|
}
|
|
61
43
|
|
|
62
|
-
const messageText =
|
|
44
|
+
const messageText = resolveMessageText(payload);
|
|
63
45
|
const approval = payload.approvalContext;
|
|
64
46
|
|
|
65
47
|
try {
|