@vellumai/assistant 0.8.12 → 0.9.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/AGENTS.md +0 -14
- package/ARCHITECTURE.md +45 -45
- package/README.md +1 -1
- package/bun.lock +200 -154
- package/docs/architecture/integrations.md +3 -3
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/security.md +10 -10
- package/docs/runbook-trusted-contacts.md +12 -12
- package/docs/skills.md +6 -6
- package/docs/workflows-testing.md +221 -0
- package/docs/workflows.md +510 -0
- package/examples/plugins/echo/README.md +5 -5
- package/knip.json +2 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +105 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +12 -0
- package/openapi.yaml +7197 -5708
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +66 -114
- package/src/__tests__/access-request-seed-content-blocks.test.ts +213 -0
- package/src/__tests__/adaptive-thinking-repair.test.ts +32 -3
- package/src/__tests__/agent-loop-output-hooks.test.ts +183 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +506 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +77 -0
- package/src/__tests__/app-compiler.test.ts +7 -1
- package/src/__tests__/app-dir-path-guard.test.ts +27 -3
- package/src/__tests__/app-executors.test.ts +43 -0
- package/src/__tests__/approval-cascade.test.ts +0 -5
- package/src/__tests__/approval-routes-http.test.ts +91 -0
- package/src/__tests__/assistant-stream-state.test.ts +107 -0
- package/src/__tests__/browser-fill-credential.test.ts +3 -3
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +63 -7
- package/src/__tests__/compaction-trail-store.test.ts +74 -1
- package/src/__tests__/compaction.benchmark.test.ts +63 -41
- package/src/__tests__/compactor-low-watermark-cut.test.ts +349 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +64 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -5
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-process-callsite.test.ts +0 -5
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
- package/src/__tests__/conversation-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
- package/src/__tests__/conversation-speed-override.test.ts +0 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +97 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
- package/src/__tests__/credential-broker-browser-fill.test.ts +2 -2
- package/src/__tests__/credential-broker-server-use.test.ts +2 -2
- package/src/__tests__/credential-broker.test.ts +1 -1
- package/src/__tests__/credential-prompt-route.test.ts +417 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault.test.ts +37 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +24 -0
- package/src/__tests__/dynamic-page-surface.test.ts +219 -0
- package/src/__tests__/empty-state-greeting-cache.test.ts +94 -0
- package/src/__tests__/gateway-flag-listener.test.ts +24 -7
- package/src/__tests__/guardian-action-sweep.test.ts +56 -219
- package/src/__tests__/guardian-routing-invariants.test.ts +138 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +99 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +87 -1
- package/src/__tests__/llm-resolver.test.ts +115 -0
- package/src/__tests__/managed-profile-guard.test.ts +6 -5
- package/src/__tests__/max-tokens-continue-hook.test.ts +184 -0
- package/src/__tests__/media-generate-image.test.ts +20 -9
- package/src/__tests__/mock-gateway-ipc.ts +23 -0
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/normalize-onboarding.test.ts +26 -0
- package/src/__tests__/notification-decision-strategy.test.ts +4 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +21 -3
- package/src/__tests__/pending-interactions-resolved-event.test.ts +62 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +72 -18
- package/src/__tests__/require-fresh-approval.test.ts +425 -1
- package/src/__tests__/resolve-app-id.test.ts +56 -0
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -0
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +408 -0
- package/src/__tests__/schedule-routes.test.ts +257 -4
- package/src/__tests__/schedule-store.test.ts +60 -0
- package/src/__tests__/schedule-tools.test.ts +247 -2
- package/src/__tests__/skill-execute-input.test.ts +85 -0
- package/src/__tests__/skill-secret-handling-guard.test.ts +21 -20
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +1 -1
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +547 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/task-progress-nudge-hook.test.ts +372 -0
- package/src/__tests__/task-scheduler.test.ts +299 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +209 -0
- package/src/__tests__/tool-result-spool.test.ts +3 -1
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +181 -0
- package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +174 -0
- package/src/agent/compaction-circuit.ts +11 -0
- package/src/agent/loop.ts +181 -12
- package/src/api/constants/call-sites.ts +12 -0
- package/src/api/events/assistant-thinking-delta.ts +10 -0
- package/src/api/events/usage-update.ts +7 -0
- package/src/api/index.ts +4 -1
- package/src/api/responses/memory-v3-selection-log.ts +18 -11
- package/src/approvals/approval-primitive.ts +2 -2
- package/src/background-wake/background-wake-routes.test.ts +5 -2
- package/src/bundler/compiler-tools.ts +1 -1
- package/src/bundler/package-resolver.ts +0 -1
- package/src/calls/call-domain.ts +1 -1
- package/src/calls/guardian-action-sweep.ts +16 -93
- package/src/cli/AGENTS.md +4 -0
- package/src/cli/commands/__tests__/schedules.test.ts +430 -1
- package/src/cli/commands/credentials.ts +28 -24
- package/src/cli/commands/image-generation.ts +23 -9
- package/src/cli/commands/notifications.ts +1 -1
- package/src/cli/commands/plugins.ts +89 -46
- package/src/cli/commands/schedules.ts +384 -11
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +69 -5
- package/src/cli/lib/__tests__/install-from-github.test.ts +15 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +81 -4
- package/src/cli/lib/inspect-plugin.ts +62 -1
- package/src/cli/lib/install-from-github.ts +52 -5
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/config/__tests__/workflows-schema.test.ts +60 -0
- package/src/config/bundled-skills/acp/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +6 -1
- package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +10 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +66 -19
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -6
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +22 -3
- package/src/config/bundled-skills/personal-page/SKILL.md +57 -0
- package/src/config/bundled-skills/personal-page/TOOLS.json +27 -0
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +17 -0
- package/src/config/bundled-skills/schedule/SKILL.md +7 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +48 -4
- package/src/config/bundled-skills/workflows/SKILL.md +214 -0
- package/src/config/bundled-skills/workflows/TOOLS.json +84 -0
- package/src/config/bundled-skills/workflows/tools/manage-workflows.ts +12 -0
- package/src/config/bundled-skills/workflows/tools/run-workflow.ts +12 -0
- package/src/config/bundled-tool-registry.ts +14 -2
- package/src/config/call-site-defaults.ts +5 -0
- package/src/config/feature-flag-registry.json +12 -4
- package/src/config/llm-context-resolution.ts +8 -0
- package/src/config/llm-resolver.ts +30 -0
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +22 -0
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +16 -0
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +77 -0
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +57 -0
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +28 -0
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +234 -0
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +48 -0
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +16 -0
- package/src/config/preloaded-apps/personal-page/src/index.html +20 -0
- package/src/config/preloaded-apps/personal-page/src/main.tsx +7 -0
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +82 -0
- package/src/config/preloaded-apps/personal-page/src/styles.css +759 -0
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/heartbeat.ts +4 -1
- package/src/config/schemas/llm.ts +33 -26
- package/src/config/schemas/memory-retrospective.ts +19 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/services.ts +5 -2
- package/src/config/schemas/workflows.ts +42 -0
- package/src/config/skills.ts +3 -3
- package/src/context/compactor.ts +273 -39
- package/src/context/post-turn-tool-result-truncation.ts +23 -6
- package/src/context/tool-result-spool.ts +12 -17
- package/src/credential-execution/executable-discovery.ts +1 -1
- package/src/credential-execution/process-manager.ts +37 -3
- package/src/credential-execution/prompted-credential.ts +205 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +14 -0
- package/src/daemon/conversation-process.ts +11 -2
- package/src/daemon/conversation-surfaces.ts +167 -3
- package/src/daemon/conversation-tool-setup.ts +103 -26
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +115 -11
- package/src/daemon/handlers/shared.ts +26 -14
- package/src/daemon/host-cu-proxy.ts +15 -12
- package/src/daemon/host-file-proxy.ts +15 -12
- package/src/daemon/host-transfer-proxy.ts +30 -24
- package/src/daemon/lifecycle.ts +40 -3
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/messages.ts +2 -10
- package/src/daemon/message-types/workflows.ts +49 -0
- package/src/daemon/parse-actual-tokens-from-error.test.ts +62 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +43 -4
- package/src/daemon/process-message.ts +6 -0
- package/src/daemon/tool-setup-types.ts +57 -0
- package/src/daemon/wake-conversation-ops.ts +18 -0
- package/src/heartbeat/heartbeat-run-store.ts +8 -2
- package/src/home/feed-types.ts +1 -1
- package/src/ipc/gateway-flag-listener.ts +28 -6
- package/src/mcp/mcp-auth-state.ts +8 -20
- package/src/media/__tests__/image-models.test.ts +57 -0
- package/src/media/image-models.ts +66 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +38 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +12 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +911 -34
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +227 -5
- package/src/memory/__tests__/memory-retrospective-state.test.ts +195 -0
- package/src/memory/__tests__/preloaded-apps.test.ts +85 -0
- package/src/memory/auto-analysis-enqueue.ts +14 -1
- package/src/memory/compaction-log-store-clickhouse.ts +6 -4
- package/src/memory/conversation-crud.ts +9 -2
- package/src/memory/conversation-disk-view.ts +1 -1
- package/src/memory/conversation-queries.ts +22 -7
- package/src/memory/db-init.ts +20 -0
- package/src/memory/db-maintenance.ts +16 -0
- package/src/memory/embedding-runtime-manager.ts +1 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +112 -14
- package/src/memory/llm-request-log-source-local.ts +19 -1
- package/src/memory/llm-request-log-source.ts +35 -6
- package/src/memory/llm-request-log-store.ts +90 -2
- package/src/memory/memory-retrospective-constants.ts +9 -0
- package/src/memory/memory-retrospective-enqueue.ts +3 -6
- package/src/memory/memory-retrospective-fork-boundary.ts +94 -0
- package/src/memory/memory-retrospective-job.ts +500 -208
- package/src/memory/memory-retrospective-startup-cleanup.ts +97 -19
- package/src/memory/memory-retrospective-state.ts +85 -2
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +40 -0
- package/src/memory/migrations/282-schedule-inference-profile.test.ts +77 -0
- package/src/memory/migrations/282-schedule-inference-profile.ts +26 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +102 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.ts +53 -0
- package/src/memory/migrations/284-workflow-runs.ts +51 -0
- package/src/memory/migrations/285-schedule-workflow-mode.ts +26 -0
- package/src/memory/migrations/286-workflow-run-trust.ts +27 -0
- package/src/memory/migrations/287-conversation-origin-channel-index.ts +15 -0
- package/src/memory/migrations/288-backfill-origin-channel-from-bindings.ts +43 -0
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +115 -0
- package/src/memory/migrations/290-schedule-capabilities.test.ts +77 -0
- package/src/memory/migrations/290-schedule-capabilities.ts +25 -0
- package/src/memory/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +96 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +571 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/preloaded-apps.ts +116 -0
- package/src/memory/schema/infrastructure.ts +4 -0
- package/src/memory/schema/memory-core.ts +4 -0
- package/src/memory/v2/__tests__/concept-page-frontmatter-schema.test.ts +45 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +11 -7
- package/src/memory/v2/__tests__/page-store.test.ts +13 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +24 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -6
- package/src/memory/v2/page-store.ts +4 -3
- package/src/memory/v2/qdrant.ts +42 -3
- package/src/memory/v2/types.ts +16 -10
- package/src/messaging/draft-store.ts +1 -1
- package/src/notifications/access-request-copy.ts +200 -113
- package/src/notifications/adapters/slack.ts +250 -111
- package/src/notifications/adapters/telegram.ts +7 -44
- package/src/notifications/approval-card-builder.ts +93 -0
- package/src/notifications/broadcaster.ts +74 -0
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/copy-composer.ts +32 -26
- package/src/notifications/decision-engine.ts +59 -7
- package/src/notifications/guardian-question-mode.ts +145 -155
- package/src/notifications/home-feed-side-effect.ts +28 -11
- package/src/notifications/notification-utils.ts +66 -0
- package/src/notifications/signal.ts +6 -0
- package/src/notifications/tool-approval-copy.ts +142 -0
- package/src/notifications/types.ts +19 -0
- package/src/permissions/threshold.ts +11 -0
- package/src/plugin-api/types.ts +16 -4
- package/src/plugins/defaults/compaction/window-manager.ts +44 -0
- package/src/plugins/defaults/index.ts +46 -0
- package/src/plugins/defaults/max-tokens-continue/continue-state-store.ts +53 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +80 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +20 -0
- package/src/plugins/defaults/max-tokens-continue/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/hooks/__tests__/user-prompt-submit.test.ts +37 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +29 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +8 -3
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +4 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +28 -18
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +67 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +122 -22
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +2 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +63 -1
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +61 -18
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +1 -1
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +39 -10
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +34 -1
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +112 -47
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +78 -15
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +206 -0
- package/src/plugins/defaults/task-progress-nudge/package.json +15 -0
- package/src/prompts/__tests__/system-prompt.test.ts +100 -1
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +5 -7
- package/src/prompts/normalize-onboarding.ts +2 -0
- package/src/prompts/persona-resolver.ts +3 -0
- package/src/prompts/system-prompt.ts +51 -2
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +3 -1
- package/src/prompts/templates/system-sections.ts +8 -3
- package/src/providers/call-site-routing.ts +6 -3
- package/src/providers/fireworks/client.ts +3 -0
- package/src/providers/inference/auth.ts +52 -46
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/__tests__/coerce-object-args.test.ts +105 -0
- package/src/providers/openai/chat-completions-provider.ts +47 -9
- package/src/providers/openai/coerce-object-args.ts +104 -0
- package/src/providers/retry.ts +8 -5
- package/src/providers/types.ts +10 -0
- package/src/runtime/__tests__/agent-wake.test.ts +629 -7
- package/src/runtime/access-request-helper.ts +16 -9
- package/src/runtime/agent-wake.ts +302 -51
- package/src/runtime/assistant-stream-state.ts +141 -8
- package/src/runtime/background-job-runner.ts +9 -0
- package/src/runtime/channel-approval-types.ts +1 -0
- package/src/runtime/channel-invite-transports/telegram.ts +6 -5
- package/src/runtime/channel-invite-transports/voice.ts +2 -2
- package/src/runtime/channel-invite-types.ts +4 -2
- package/src/runtime/channel-retry-sweep.ts +19 -41
- package/src/runtime/finalize-event-delivery.ts +72 -0
- package/src/runtime/guardian-action-message-composer.ts +0 -54
- package/src/runtime/http-server.ts +6 -14
- package/src/runtime/http-types.ts +0 -1
- package/src/runtime/message-composer-types.ts +0 -9
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +63 -0
- package/src/runtime/middleware/auth.ts +27 -3
- package/src/runtime/middleware/rate-limiter.ts +28 -1
- package/src/runtime/migrations/vbundle-builder.ts +6 -5
- package/src/runtime/pending-interactions.ts +20 -1
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +232 -173
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +18 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +436 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +11 -0
- package/src/runtime/routes/approval-routes.ts +35 -8
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -1
- package/src/runtime/routes/btw-routes.ts +37 -1
- package/src/runtime/routes/channel-delivery-routes.ts +11 -7
- package/src/runtime/routes/channel-route-definitions.ts +3 -0
- package/src/runtime/routes/channel-route-shared.ts +3 -1
- package/src/runtime/routes/consolidation-routes.ts +17 -13
- package/src/runtime/routes/conversation-compaction-routes.ts +159 -119
- package/src/runtime/routes/conversation-list-routes.ts +41 -4
- package/src/runtime/routes/conversation-query-routes.ts +196 -11
- package/src/runtime/routes/conversation-routes.ts +15 -1
- package/src/runtime/routes/credential-prompt-routes.ts +39 -17
- package/src/runtime/routes/empty-state-greeting-cache.ts +65 -0
- package/src/runtime/routes/heartbeat-routes.ts +18 -13
- package/src/runtime/routes/image-generation-routes.ts +20 -2
- package/src/runtime/routes/inbound-message-handler.ts +13 -12
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +32 -31
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +7 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -21
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +6 -15
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/log-export/AGENTS.md +1 -1
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +5 -9
- package/src/runtime/routes/plugins-routes.ts +26 -0
- package/src/runtime/routes/ps-routes.ts +10 -8
- package/src/runtime/routes/retrospective-routes.ts +235 -0
- package/src/runtime/routes/runs-pagination.ts +75 -0
- package/src/runtime/routes/schedule-routes.ts +367 -59
- package/src/runtime/routes/sounds-config-routes.ts +239 -0
- package/src/runtime/routes/surface-action-routes.ts +84 -4
- package/src/runtime/routes/workflow-routes.test.ts +372 -0
- package/src/runtime/routes/workflow-routes.ts +363 -0
- package/src/runtime/routes/workspace-routes.test.ts +61 -1
- package/src/runtime/routes/workspace-routes.ts +26 -1
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +38 -0
- package/src/runtime/services/analyze-conversation.ts +26 -13
- package/src/schedule/inference-profile.ts +28 -0
- package/src/schedule/schedule-store.ts +152 -4
- package/src/schedule/scheduler-types.ts +6 -0
- package/src/schedule/scheduler.ts +96 -0
- package/src/security/secret-allowlist.ts +1 -1
- package/src/skills/path-classifier.ts +1 -1
- package/src/tools/apps/executors.ts +23 -0
- package/src/tools/apps/resolve-app-id.ts +42 -0
- package/src/tools/browser/browser-execution.ts +9 -11
- package/src/tools/credentials/broker.ts +4 -4
- package/src/tools/credentials/vault.ts +26 -137
- package/src/tools/executor.ts +69 -0
- package/src/tools/flag-gated-tools.test.ts +76 -0
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/registry.ts +51 -0
- package/src/tools/schedule/create.ts +77 -1
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +73 -1
- package/src/tools/skills/execute.ts +56 -0
- package/src/tools/terminal/shell.ts +1 -1
- package/src/tools/ui-surface/definitions.ts +91 -2
- package/src/tools/workflows/manage-workflows.ts +183 -0
- package/src/tools/workflows/run-workflow.test.ts +442 -0
- package/src/tools/workflows/run-workflow.ts +88 -0
- package/src/types/onboarding-context.ts +2 -0
- package/src/usage/attribution.ts +24 -0
- package/src/util/canonicalize-identity.ts +12 -3
- package/src/util/platform.ts +17 -17
- package/src/watcher/__tests__/engine.test.ts +24 -0
- package/src/watcher/__tests__/telemetry.test.ts +135 -0
- package/src/watcher/engine.ts +7 -0
- package/src/watcher/telemetry.ts +74 -0
- package/src/workflows/capabilities.test.ts +365 -0
- package/src/workflows/capabilities.ts +359 -0
- package/src/workflows/deterministic-stringify.ts +27 -0
- package/src/workflows/engine-integration.test.ts +656 -0
- package/src/workflows/engine.test.ts +1144 -0
- package/src/workflows/engine.ts +1078 -0
- package/src/workflows/fanout-load.test.ts +168 -0
- package/src/workflows/journal-store.test.ts +369 -0
- package/src/workflows/journal-store.ts +470 -0
- package/src/workflows/leaf-runner.test.ts +704 -0
- package/src/workflows/leaf-runner.ts +589 -0
- package/src/workflows/library.test.ts +134 -0
- package/src/workflows/library.ts +124 -0
- package/src/workflows/run-manager.test.ts +711 -0
- package/src/workflows/run-manager.ts +593 -0
- package/src/workflows/sandbox-escape.test.ts +339 -0
- package/src/workflows/sandbox.test.ts +251 -0
- package/src/workflows/sandbox.ts +447 -0
- package/src/workspace/adaptive-thinking-repair.ts +33 -11
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +1 -1
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +1 -1
- package/src/workspace/migrations/026-backfill-install-meta.ts +1 -1
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +2 -1
- package/src/workspace/migrations/031-drop-user-md.ts +1 -4
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +1 -1
- package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +5 -2
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +1 -1
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +8 -2
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +41 -14
- package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +69 -0
- package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +83 -0
- package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +133 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/migrations/runner.ts +1 -1
- package/tsconfig.json +1 -1
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -200
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -579
- package/src/__tests__/guardian-action-store.test.ts +0 -106
- package/src/daemon/guardian-action-generators.ts +0 -71
- package/src/memory/guardian-action-store.ts +0 -484
- package/src/runtime/guardian-action-grant-minter.ts +0 -150
|
@@ -5,74 +5,105 @@
|
|
|
5
5
|
* post-generation enforcement to ensure required directives always appear.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
10
|
+
import { buildApprovalCardBlocks } from "./approval-card-builder.js";
|
|
11
|
+
import {
|
|
12
|
+
nonEmpty,
|
|
13
|
+
sanitizeIdentityField,
|
|
14
|
+
sanitizeMessagePreview,
|
|
15
|
+
} from "./notification-utils.js";
|
|
16
|
+
|
|
17
|
+
// ── Zod schema for access-request payloads ──────────────────────────────────
|
|
18
|
+
|
|
19
|
+
/** Accepts string, null, or any other type — coerces non-strings to undefined. */
|
|
20
|
+
const optStr = z
|
|
21
|
+
.unknown()
|
|
22
|
+
.transform((v) => (typeof v === "string" ? v : undefined));
|
|
23
|
+
|
|
24
|
+
/** Accepts boolean or any other type — coerces non-true to undefined. */
|
|
25
|
+
const optBool = z.unknown().transform((v) => (v === true ? true : undefined));
|
|
26
|
+
|
|
27
|
+
export const AccessRequestPayloadSchema = z.object({
|
|
28
|
+
requestId: optStr,
|
|
29
|
+
requestCode: optStr,
|
|
30
|
+
sourceChannel: optStr,
|
|
31
|
+
conversationExternalId: optStr,
|
|
32
|
+
actorExternalId: optStr,
|
|
33
|
+
actorDisplayName: optStr,
|
|
34
|
+
actorUsername: optStr,
|
|
35
|
+
senderIdentifier: optStr,
|
|
36
|
+
guardianBindingChannel: optStr,
|
|
37
|
+
guardianResolutionSource: optStr,
|
|
38
|
+
previousMemberStatus: optStr,
|
|
39
|
+
messagePreview: optStr,
|
|
40
|
+
isStranger: optBool,
|
|
41
|
+
isRestricted: optBool,
|
|
42
|
+
messageTs: optStr,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export type ParsedAccessRequestPayload = z.infer<
|
|
46
|
+
typeof AccessRequestPayloadSchema
|
|
47
|
+
>;
|
|
48
|
+
|
|
49
|
+
export function parseAccessRequestPayload(
|
|
50
|
+
payload: Record<string, unknown>,
|
|
51
|
+
): ParsedAccessRequestPayload {
|
|
52
|
+
return AccessRequestPayloadSchema.parse(payload);
|
|
17
53
|
}
|
|
18
54
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
55
|
+
// ── Warnings ────────────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build a list of human-readable warning strings for an access request.
|
|
59
|
+
* Used by both the Slack Block Kit card and the plain-text contract.
|
|
60
|
+
*/
|
|
61
|
+
export function buildAccessRequestWarnings(
|
|
62
|
+
p: ParsedAccessRequestPayload,
|
|
63
|
+
): string[] {
|
|
64
|
+
const warnings: string[] = [];
|
|
65
|
+
if (p.previousMemberStatus === "revoked") {
|
|
66
|
+
warnings.push("This user was previously revoked.");
|
|
67
|
+
}
|
|
68
|
+
if (p.isStranger) {
|
|
69
|
+
warnings.push("External Slack user (not in this workspace).");
|
|
70
|
+
}
|
|
71
|
+
if (p.isRestricted) {
|
|
72
|
+
warnings.push("Guest / restricted account.");
|
|
73
|
+
}
|
|
74
|
+
return warnings;
|
|
23
75
|
}
|
|
24
76
|
|
|
25
|
-
// ──
|
|
77
|
+
// ── Slack conversation helpers ───────────────────────────────────────────────
|
|
26
78
|
|
|
27
|
-
|
|
79
|
+
/** Slack DM conversation IDs start with `D` followed by alphanumeric chars. */
|
|
80
|
+
export function isSlackDmConversation(conversationExternalId: string): boolean {
|
|
81
|
+
return /^D[A-Z0-9]+$/i.test(conversationExternalId);
|
|
82
|
+
}
|
|
28
83
|
|
|
29
84
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* -
|
|
33
|
-
* - Clamps to IDENTITY_FIELD_MAX_LENGTH characters.
|
|
34
|
-
* - Wraps in quotes to neutralize instruction-like payload text.
|
|
85
|
+
* Build a Slack message permalink from a channel ID and message timestamp.
|
|
86
|
+
* Format: https://slack.com/archives/{channelId}/p{ts_without_dot}
|
|
87
|
+
* Workspace-agnostic — resolves for any authenticated Slack viewer.
|
|
35
88
|
*/
|
|
36
|
-
export function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
: stripped;
|
|
42
|
-
return clamped;
|
|
89
|
+
export function buildSlackMessagePermalink(
|
|
90
|
+
conversationExternalId: string,
|
|
91
|
+
messageTs: string,
|
|
92
|
+
): string {
|
|
93
|
+
return `https://slack.com/archives/${conversationExternalId}/p${messageTs.replace(".", "")}`;
|
|
43
94
|
}
|
|
44
95
|
|
|
45
|
-
|
|
46
|
-
payload
|
|
47
|
-
): string {
|
|
48
|
-
const requester = sanitizeIdentityField(
|
|
49
|
-
|
|
50
|
-
);
|
|
51
|
-
const
|
|
52
|
-
typeof payload.sourceChannel === "string"
|
|
53
|
-
? payload.sourceChannel
|
|
54
|
-
: undefined;
|
|
55
|
-
const callerName = nonEmpty(
|
|
56
|
-
typeof payload.actorDisplayName === "string"
|
|
57
|
-
? payload.actorDisplayName
|
|
58
|
-
: undefined,
|
|
59
|
-
);
|
|
60
|
-
const actorUsername = nonEmpty(
|
|
61
|
-
typeof payload.actorUsername === "string"
|
|
62
|
-
? payload.actorUsername
|
|
63
|
-
: undefined,
|
|
64
|
-
);
|
|
65
|
-
const actorExternalId = nonEmpty(
|
|
66
|
-
typeof payload.actorExternalId === "string"
|
|
67
|
-
? payload.actorExternalId
|
|
68
|
-
: undefined,
|
|
69
|
-
);
|
|
96
|
+
/** Internal typed implementation — avoids re-parsing when called from
|
|
97
|
+
* buildAccessRequestContractText which has already parsed the payload. */
|
|
98
|
+
function buildIdentityLineFromParsed(p: ParsedAccessRequestPayload): string {
|
|
99
|
+
const requester = sanitizeIdentityField(p.senderIdentifier || "Someone");
|
|
100
|
+
const callerName = nonEmpty(p.actorDisplayName);
|
|
101
|
+
const actorUsername = nonEmpty(p.actorUsername);
|
|
102
|
+
const actorExternalId = nonEmpty(p.actorExternalId);
|
|
70
103
|
|
|
71
|
-
if (sourceChannel === "phone" && callerName) {
|
|
104
|
+
if (p.sourceChannel === "phone" && callerName) {
|
|
72
105
|
const safeName = sanitizeIdentityField(callerName);
|
|
73
|
-
const safeId = sanitizeIdentityField(
|
|
74
|
-
str(payload.actorExternalId, requester),
|
|
75
|
-
);
|
|
106
|
+
const safeId = sanitizeIdentityField(p.actorExternalId || requester);
|
|
76
107
|
return `${safeName} (${safeId}) is calling and requesting access to the assistant.`;
|
|
77
108
|
}
|
|
78
109
|
|
|
@@ -84,11 +115,10 @@ export function buildAccessRequestIdentityLine(
|
|
|
84
115
|
const sanitizedExternalId = actorExternalId
|
|
85
116
|
? sanitizeIdentityField(actorExternalId)
|
|
86
117
|
: undefined;
|
|
87
|
-
// When the requester is a raw Slack user ID
|
|
88
|
-
//
|
|
89
|
-
// format it as a Slack mention so it renders as a clickable display name.
|
|
118
|
+
// When the requester is a raw Slack user ID, format it as a Slack mention
|
|
119
|
+
// so Slack auto-renders it as a clickable display name.
|
|
90
120
|
const formattedRequester =
|
|
91
|
-
sourceChannel === "slack" && /^U[A-Z0-9]+$/i.test(requester)
|
|
121
|
+
p.sourceChannel === "slack" && /^U[A-Z0-9]+$/i.test(requester)
|
|
92
122
|
? `<@${requester}>`
|
|
93
123
|
: requester;
|
|
94
124
|
const parts = [formattedRequester];
|
|
@@ -100,39 +130,23 @@ export function buildAccessRequestIdentityLine(
|
|
|
100
130
|
sanitizedExternalId !== requester &&
|
|
101
131
|
sanitizedExternalId !== sanitizedUsername
|
|
102
132
|
) {
|
|
103
|
-
// For Slack, use the <@U...> mention format so Slack auto-renders
|
|
104
|
-
// the user ID as a clickable display name.
|
|
105
133
|
const formattedId =
|
|
106
|
-
sourceChannel === "slack" && /^U[A-Z0-9]+$/i.test(sanitizedExternalId)
|
|
134
|
+
p.sourceChannel === "slack" && /^U[A-Z0-9]+$/i.test(sanitizedExternalId)
|
|
107
135
|
? `<@${sanitizedExternalId}>`
|
|
108
136
|
: `[${sanitizedExternalId}]`;
|
|
109
137
|
parts.push(formattedId);
|
|
110
138
|
}
|
|
111
|
-
if (sourceChannel) {
|
|
112
|
-
parts.push(`via ${sourceChannel}`);
|
|
139
|
+
if (p.sourceChannel) {
|
|
140
|
+
parts.push(`via ${p.sourceChannel}`);
|
|
113
141
|
}
|
|
114
142
|
|
|
115
143
|
return `${parts.join(" ")} is requesting access to the assistant.`;
|
|
116
144
|
}
|
|
117
145
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Sanitize an untrusted message preview for inclusion in notification copy.
|
|
124
|
-
*
|
|
125
|
-
* Like {@link sanitizeIdentityField} but uses the higher
|
|
126
|
-
* MESSAGE_PREVIEW_MAX_LENGTH limit (200 chars) instead of the identity
|
|
127
|
-
* field limit (120 chars).
|
|
128
|
-
*/
|
|
129
|
-
export function sanitizeMessagePreview(value: string): string {
|
|
130
|
-
const stripped = value.replace(/[\x00-\x1f\x7f-\x9f\r\n]+/g, " ").trim();
|
|
131
|
-
const clamped =
|
|
132
|
-
stripped.length > MESSAGE_PREVIEW_MAX_LENGTH
|
|
133
|
-
? stripped.slice(0, MESSAGE_PREVIEW_MAX_LENGTH) + "…"
|
|
134
|
-
: stripped;
|
|
135
|
-
return clamped;
|
|
146
|
+
export function buildAccessRequestIdentityLine(
|
|
147
|
+
payload: Record<string, unknown>,
|
|
148
|
+
): string {
|
|
149
|
+
return buildIdentityLineFromParsed(parseAccessRequestPayload(payload));
|
|
136
150
|
}
|
|
137
151
|
|
|
138
152
|
/**
|
|
@@ -142,13 +156,10 @@ export function sanitizeMessagePreview(value: string): string {
|
|
|
142
156
|
*
|
|
143
157
|
* Returns `undefined` when no usable preview is available.
|
|
144
158
|
*/
|
|
145
|
-
function
|
|
146
|
-
|
|
159
|
+
function buildMessagePreviewFromParsed(
|
|
160
|
+
p: ParsedAccessRequestPayload,
|
|
147
161
|
): string | undefined {
|
|
148
|
-
const raw =
|
|
149
|
-
typeof payload.messagePreview === "string"
|
|
150
|
-
? payload.messagePreview
|
|
151
|
-
: undefined;
|
|
162
|
+
const raw = p.messagePreview;
|
|
152
163
|
if (!raw) return undefined;
|
|
153
164
|
|
|
154
165
|
const sanitized = sanitizeMessagePreview(raw);
|
|
@@ -252,32 +263,35 @@ export function hasInviteFlowDirective(text: string | undefined): boolean {
|
|
|
252
263
|
export function buildAccessRequestContractText(
|
|
253
264
|
payload: Record<string, unknown>,
|
|
254
265
|
): string {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
);
|
|
258
|
-
const previousMemberStatus =
|
|
259
|
-
typeof payload.previousMemberStatus === "string"
|
|
260
|
-
? payload.previousMemberStatus
|
|
261
|
-
: undefined;
|
|
262
|
-
|
|
263
|
-
const guardianResolutionSource =
|
|
264
|
-
typeof payload.guardianResolutionSource === "string"
|
|
265
|
-
? payload.guardianResolutionSource
|
|
266
|
-
: undefined;
|
|
267
|
-
const sourceChannel =
|
|
268
|
-
typeof payload.sourceChannel === "string"
|
|
269
|
-
? payload.sourceChannel
|
|
270
|
-
: undefined;
|
|
266
|
+
const p = parseAccessRequestPayload(payload);
|
|
267
|
+
const requestCode = nonEmpty(p.requestCode);
|
|
271
268
|
|
|
272
269
|
const lines: string[] = [];
|
|
273
|
-
lines.push(
|
|
274
|
-
|
|
270
|
+
lines.push(buildIdentityLineFromParsed(p));
|
|
271
|
+
|
|
272
|
+
const preview = buildMessagePreviewFromParsed(p);
|
|
275
273
|
if (preview) {
|
|
276
274
|
lines.push(preview);
|
|
277
275
|
}
|
|
278
|
-
|
|
279
|
-
|
|
276
|
+
|
|
277
|
+
// Unified warnings: revoked status + trust signals.
|
|
278
|
+
for (const warning of buildAccessRequestWarnings(p)) {
|
|
279
|
+
lines.push(`Note: ${warning.charAt(0).toLowerCase()}${warning.slice(1)}`);
|
|
280
280
|
}
|
|
281
|
+
|
|
282
|
+
// Conversation context: source channel + permalink when available.
|
|
283
|
+
if (p.sourceChannel === "slack" && p.conversationExternalId) {
|
|
284
|
+
const permalink = p.messageTs
|
|
285
|
+
? buildSlackMessagePermalink(p.conversationExternalId, p.messageTs)
|
|
286
|
+
: undefined;
|
|
287
|
+
const isDm = isSlackDmConversation(p.conversationExternalId);
|
|
288
|
+
const channelLabel = isDm ? "Direct message" : p.conversationExternalId;
|
|
289
|
+
const source = permalink
|
|
290
|
+
? `Source: Slack — ${channelLabel} (${permalink})`
|
|
291
|
+
: `Source: Slack — ${channelLabel}`;
|
|
292
|
+
lines.push(source);
|
|
293
|
+
}
|
|
294
|
+
|
|
281
295
|
if (requestCode) {
|
|
282
296
|
const code = requestCode.toUpperCase();
|
|
283
297
|
lines.push(
|
|
@@ -285,14 +299,87 @@ export function buildAccessRequestContractText(
|
|
|
285
299
|
);
|
|
286
300
|
}
|
|
287
301
|
lines.push(buildAccessRequestInviteDirective());
|
|
302
|
+
|
|
288
303
|
if (
|
|
289
|
-
(guardianResolutionSource === "vellum-anchor" ||
|
|
290
|
-
guardianResolutionSource === "none") &&
|
|
291
|
-
sourceChannel
|
|
304
|
+
(p.guardianResolutionSource === "vellum-anchor" ||
|
|
305
|
+
p.guardianResolutionSource === "none") &&
|
|
306
|
+
p.sourceChannel
|
|
292
307
|
) {
|
|
293
308
|
lines.push(
|
|
294
|
-
`Note: You haven't verified your identity on ${sourceChannel} yet. If this was you trying to message your assistant, say "help me verify as guardian on ${sourceChannel}" to set up direct access.`,
|
|
309
|
+
`Note: You haven't verified your identity on ${p.sourceChannel} yet. If this was you trying to message your assistant, say "help me verify as guardian on ${p.sourceChannel}" to set up direct access.`,
|
|
295
310
|
);
|
|
296
311
|
}
|
|
297
312
|
return lines.join("\n");
|
|
298
313
|
}
|
|
314
|
+
|
|
315
|
+
// ── Seed content blocks (Surface-based rendering) ───────────────────────────
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Build structured content blocks for an access request notification seed
|
|
319
|
+
* message. Produces a `ui_surface` card block that the web/macOS/iOS apps
|
|
320
|
+
* render as an interactive card via `SurfaceRouter → CardSurface`, plus a
|
|
321
|
+
* plain-text fallback block for search, CLI display, and backward-compatible
|
|
322
|
+
* clients that don't support surfaces.
|
|
323
|
+
*/
|
|
324
|
+
export function buildAccessRequestSeedContentBlocks(
|
|
325
|
+
payload: Record<string, unknown>,
|
|
326
|
+
): unknown[] {
|
|
327
|
+
const p = parseAccessRequestPayload(payload);
|
|
328
|
+
|
|
329
|
+
const rawName = nonEmpty(p.actorDisplayName) ?? nonEmpty(p.senderIdentifier);
|
|
330
|
+
const displayName = rawName ? sanitizeIdentityField(rawName) : "Someone";
|
|
331
|
+
|
|
332
|
+
const metadata: Array<{ label: string; value: string }> = [];
|
|
333
|
+
|
|
334
|
+
if (p.actorUsername) {
|
|
335
|
+
metadata.push({
|
|
336
|
+
label: "Username",
|
|
337
|
+
value: `@${sanitizeIdentityField(p.actorUsername)}`,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (p.sourceChannel === "slack" && p.conversationExternalId) {
|
|
342
|
+
const isDm = isSlackDmConversation(p.conversationExternalId);
|
|
343
|
+
metadata.push({
|
|
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
|
+
}
|
|
352
|
+
|
|
353
|
+
const warnings = buildAccessRequestWarnings(p);
|
|
354
|
+
const bodyParts: string[] = [];
|
|
355
|
+
|
|
356
|
+
if (p.messagePreview) {
|
|
357
|
+
bodyParts.push(`> "${sanitizeMessagePreview(p.messagePreview)}"`);
|
|
358
|
+
}
|
|
359
|
+
for (const w of warnings) {
|
|
360
|
+
bodyParts.push(`⚠️ ${w}`);
|
|
361
|
+
}
|
|
362
|
+
if (p.sourceChannel === "slack" && p.conversationExternalId && p.messageTs) {
|
|
363
|
+
const permalink = buildSlackMessagePermalink(
|
|
364
|
+
p.conversationExternalId,
|
|
365
|
+
p.messageTs,
|
|
366
|
+
);
|
|
367
|
+
bodyParts.push(`[View message](${permalink})`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const body =
|
|
371
|
+
bodyParts.length > 0
|
|
372
|
+
? bodyParts.join("\n\n")
|
|
373
|
+
: "No additional context available.";
|
|
374
|
+
|
|
375
|
+
return buildApprovalCardBlocks({
|
|
376
|
+
surfaceIdPrefix: "access-request",
|
|
377
|
+
cardTitle: "Access Request",
|
|
378
|
+
requesterName: displayName,
|
|
379
|
+
subtitle: "Requesting access to the assistant",
|
|
380
|
+
body,
|
|
381
|
+
metadata,
|
|
382
|
+
requestId: p.requestId,
|
|
383
|
+
fallbackText: buildAccessRequestContractText(payload),
|
|
384
|
+
});
|
|
385
|
+
}
|