@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
|
@@ -486,14 +486,14 @@ The proxy subsystem is fully wired, including credential injection. The session
|
|
|
486
486
|
|
|
487
487
|
## Conversation Disk View — Filesystem-Based Conversation Access
|
|
488
488
|
|
|
489
|
-
The conversation disk view projects conversation metadata, messages, and attachments to a browsable filesystem layout under
|
|
489
|
+
The conversation disk view projects conversation metadata, messages, and attachments to a browsable filesystem layout under `$VELLUM_WORKSPACE_DIR/conversations/`. This enables the assistant to search, read, and manipulate conversation data (including media attachments) using standard file tools (`read_file`, `glob`, `grep`) rather than dedicated asset search tools.
|
|
490
490
|
|
|
491
491
|
### Directory Layout
|
|
492
492
|
|
|
493
493
|
Each conversation is projected to a directory named `{isoDate}_{id}`:
|
|
494
494
|
|
|
495
495
|
```
|
|
496
|
-
|
|
496
|
+
$VELLUM_WORKSPACE_DIR/conversations/
|
|
497
497
|
2025-01-15T10-30-00.000Z_abc123/
|
|
498
498
|
meta.json # Conversation metadata (id, title, type, channel, timestamps)
|
|
499
499
|
messages.jsonl # Flattened message log (one JSON object per line)
|
|
@@ -506,7 +506,7 @@ Each conversation is projected to a directory named `{isoDate}_{id}`:
|
|
|
506
506
|
|
|
507
507
|
The disk view is updated at the daemon level, not automatically by the DB CRUD layer. Conversation creation, metadata updates, and deletion are synced from `conversation-crud.ts`, but message sync (`syncMessageToDisk`) is only called from daemon-level code paths (e.g. `conversation-messaging.ts`) — not from the CRUD `addMessage()` function. This means `messages.jsonl` reflects messages processed through the daemon's messaging pipeline, not every message write. All disk writes are best-effort; failures are logged but never thrown, so the disk view cannot break DB operations.
|
|
508
508
|
|
|
509
|
-
> **Privacy note:** Conversation disk-view files live under
|
|
509
|
+
> **Privacy note:** Conversation disk-view files live under `$VELLUM_WORKSPACE_DIR/conversations/`. Workspace files are not included in diagnostic log exports ("Send logs to Vellum"). For conversation-scoped exports, conversation data is included as structured JSON tables (e.g. `messages.json`, `llm-request-logs.json`), not as a raw database dump.
|
|
510
510
|
|
|
511
511
|
```mermaid
|
|
512
512
|
sequenceDiagram
|
|
@@ -445,7 +445,7 @@ graph TB
|
|
|
445
445
|
|
|
446
446
|
### Key design decisions
|
|
447
447
|
|
|
448
|
-
- **Scope**: Sandbox workspace only (
|
|
448
|
+
- **Scope**: Sandbox workspace only (`$VELLUM_WORKSPACE_DIR`). Non-recursive — only top-level directories.
|
|
449
449
|
- **Bounded**: Maximum 120 directory entries (`MAX_TOP_LEVEL_ENTRIES`). Excess is truncated with a note.
|
|
450
450
|
- **Prepend, not append**: The workspace block is prepended to the user message content so that Anthropic cache breakpoints continue to land on the trailing user text block, preserving prompt cache efficiency.
|
|
451
451
|
- **Persists in history**: The injected `<workspace>` block persists in conversation history, giving the model workspace grounding across turns. Legacy `<workspace_top_level>` blocks from pre-change history are stripped for backward compatibility.
|
|
@@ -512,7 +512,7 @@ graph TB
|
|
|
512
512
|
|
|
513
513
|
## Workspace Git Tracking — Change Management
|
|
514
514
|
|
|
515
|
-
The workspace sandbox (
|
|
515
|
+
The workspace sandbox (`$VELLUM_WORKSPACE_DIR`) is automatically tracked by a per-workspace git repository. Every file change made by the assistant is captured in structured commits, providing a full audit trail and natural undo/history exploration via standard git commands.
|
|
516
516
|
|
|
517
517
|
### Architecture overview
|
|
518
518
|
|
|
@@ -94,13 +94,13 @@ When `autoApproveUpTo` is `"none"`, `skill_load` without a matching rule is alwa
|
|
|
94
94
|
|
|
95
95
|
Skills that use existing system tools (`bash`, `file_read`, `web_fetch`, etc.) **do not expand the assistant's capability surface**. The assistant already has access to these tools based on its trust rules; a skill that teaches `curl https://api.example.com/v1/endpoint -d "..."` presents identical risk to a user asking the assistant to run that same command directly. The risk is governed entirely by the bash risk classifier and the user's `autoApproveUpTo` threshold — the same path as any other bash invocation.
|
|
96
96
|
|
|
97
|
-
The threat vectors that skills
|
|
97
|
+
The threat vectors that skills _do_ introduce are:
|
|
98
98
|
|
|
99
|
-
| Threat
|
|
100
|
-
|
|
99
|
+
| Threat | Mitigation |
|
|
100
|
+
| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
101
101
|
| **Skill source file mutations** — editing a skill's own source files could inject behavior on next load | `isSkillSourcePath()` escalates `file_write`/`file_edit` targeting skill roots to **High**, requiring explicit approval |
|
|
102
|
-
| **New skill-origin tools** — tools registered and invoked through the skill IPC contract
|
|
103
|
-
| **Credential storage** — a skill collecting and storing an API key
|
|
102
|
+
| **New skill-origin tools** — tools registered and invoked through the skill IPC contract | Skill-origin tools with no matching trust rule are always **prompted**, regardless of their risk level |
|
|
103
|
+
| **Credential storage** — a skill collecting and storing an API key | Mediated by the secure credential prompt flow (`assistant credentials prompt`) |
|
|
104
104
|
|
|
105
105
|
What skills do **not** introduce:
|
|
106
106
|
|
|
@@ -278,11 +278,11 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
|
|
|
278
278
|
|
|
279
279
|
### Storage Layout
|
|
280
280
|
|
|
281
|
-
| Component | Location
|
|
282
|
-
| ------------------- |
|
|
283
|
-
| Secret values | CES credential store or encrypted file store
|
|
284
|
-
| Credential metadata |
|
|
285
|
-
| Config |
|
|
281
|
+
| Component | Location | What it stores |
|
|
282
|
+
| ------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
283
|
+
| Secret values | CES credential store or encrypted file store | Encrypted credential values keyed as `credential/{service}/{field}`. Stored via CES RPC (primary), CES HTTP (containerized), or encrypted file store (fallback). |
|
|
284
|
+
| Credential metadata | `$VELLUM_WORKSPACE_DIR/data/credentials/metadata.json` | Service, field, label, policy (allowedTools, allowedDomains), timestamps |
|
|
285
|
+
| Config | `$VELLUM_WORKSPACE_DIR/config.*` | `secretDetection` settings: enabled, blockIngress, allowOneTimeSend |
|
|
286
286
|
|
|
287
287
|
### Key Files
|
|
288
288
|
|
|
@@ -90,7 +90,7 @@ Access requests are stored in the `channel_guardian_approval_requests` table. Us
|
|
|
90
90
|
### Via SQLite CLI
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
sqlite3
|
|
93
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
94
94
|
"SELECT id, channel, requester_external_user_id, requester_chat_id, \
|
|
95
95
|
guardian_external_user_id, status, tool_name, created_at, expires_at \
|
|
96
96
|
FROM channel_guardian_approval_requests \
|
|
@@ -101,7 +101,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
101
101
|
### Check all access requests (including resolved)
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
sqlite3
|
|
104
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
105
105
|
"SELECT id, channel, requester_external_user_id, status, \
|
|
106
106
|
decided_by_external_user_id, created_at \
|
|
107
107
|
FROM channel_guardian_approval_requests \
|
|
@@ -114,7 +114,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
114
114
|
Verification challenges are stored in `channel_verification_sessions`. Active sessions have `status = 'awaiting_response'` and `expires_at > now`.
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
sqlite3
|
|
117
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
118
118
|
"SELECT id, channel, status, identity_binding_status, \
|
|
119
119
|
expected_external_user_id, expected_chat_id, expected_phone_e164, \
|
|
120
120
|
expires_at, created_at \
|
|
@@ -158,7 +158,7 @@ curl -s -X PATCH "$BASE/v1/contact-channels/$CHANNEL_ID" \
|
|
|
158
158
|
If the HTTP API is unavailable:
|
|
159
159
|
|
|
160
160
|
```bash
|
|
161
|
-
sqlite3
|
|
161
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
162
162
|
"UPDATE contact_channels \
|
|
163
163
|
SET status = 'revoked', revoked_reason = 'Emergency operator revocation', \
|
|
164
164
|
updated_at = $(date +%s)000 \
|
|
@@ -172,7 +172,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
172
172
|
If a user is getting "invalid or expired code" errors, they may be rate-limited:
|
|
173
173
|
|
|
174
174
|
```bash
|
|
175
|
-
sqlite3
|
|
175
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
176
176
|
"SELECT * FROM channel_guardian_rate_limits \
|
|
177
177
|
WHERE external_user_id = 'TARGET_USER_ID' \
|
|
178
178
|
OR chat_id = 'TARGET_CHAT_ID' \
|
|
@@ -182,7 +182,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
182
182
|
### Reset rate limits for a user
|
|
183
183
|
|
|
184
184
|
```bash
|
|
185
|
-
sqlite3
|
|
185
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
186
186
|
"DELETE FROM channel_guardian_rate_limits \
|
|
187
187
|
WHERE external_user_id = 'TARGET_USER_ID' AND channel = 'telegram';"
|
|
188
188
|
```
|
|
@@ -190,7 +190,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
190
190
|
### Check verification challenge state
|
|
191
191
|
|
|
192
192
|
```bash
|
|
193
|
-
sqlite3
|
|
193
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
194
194
|
"SELECT id, channel, status, identity_binding_status, \
|
|
195
195
|
expected_external_user_id, expected_chat_id, expected_phone_e164, \
|
|
196
196
|
expires_at, consumed_by_external_user_id \
|
|
@@ -215,7 +215,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
215
215
|
### Check if the access request notification was delivered
|
|
216
216
|
|
|
217
217
|
```bash
|
|
218
|
-
sqlite3
|
|
218
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
219
219
|
"SELECT ne.id, ne.source_event_name, ne.dedupe_key, ne.created_at, \
|
|
220
220
|
nd.channel, nd.status, nd.confidence \
|
|
221
221
|
FROM notification_events ne \
|
|
@@ -227,7 +227,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
227
227
|
### Check delivery records
|
|
228
228
|
|
|
229
229
|
```bash
|
|
230
|
-
sqlite3
|
|
230
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
231
231
|
"SELECT ndel.id, ndel.channel, ndel.status, ndel.error_message, \
|
|
232
232
|
ndel.created_at, ne.source_event_name \
|
|
233
233
|
FROM notification_deliveries ndel \
|
|
@@ -239,7 +239,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
239
239
|
### Check lifecycle signals
|
|
240
240
|
|
|
241
241
|
```bash
|
|
242
|
-
sqlite3
|
|
242
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
243
243
|
"SELECT source_event_name, source_channel, dedupe_key, created_at \
|
|
244
244
|
FROM notification_events \
|
|
245
245
|
WHERE source_event_name LIKE 'ingress.trusted_contact.%' \
|
|
@@ -295,7 +295,7 @@ curl -s -X POST "$BASE/v1/contacts" \
|
|
|
295
295
|
Expired sessions are already invisible to the verification flow (filtered by `expires_at`), but you can clean them up:
|
|
296
296
|
|
|
297
297
|
```bash
|
|
298
|
-
sqlite3
|
|
298
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
299
299
|
"DELETE FROM channel_verification_sessions \
|
|
300
300
|
WHERE expires_at < $(date +%s)000 \
|
|
301
301
|
AND status IN ('awaiting_response', 'pending_bootstrap');"
|
|
@@ -306,7 +306,7 @@ sqlite3 ~/.vellum/workspace/data/db/assistant.db \
|
|
|
306
306
|
The `sweepExpiredGuardianApprovals()` timer handles this automatically every 60 seconds, but manual cleanup:
|
|
307
307
|
|
|
308
308
|
```bash
|
|
309
|
-
sqlite3
|
|
309
|
+
sqlite3 "$VELLUM_WORKSPACE_DIR"/data/db/assistant.db \
|
|
310
310
|
"UPDATE channel_guardian_approval_requests \
|
|
311
311
|
SET status = 'expired' \
|
|
312
312
|
WHERE status = 'pending' AND expires_at < $(date +%s)000;"
|
package/docs/skills.md
CHANGED
|
@@ -6,7 +6,7 @@ This document describes the security model for the Vellum Assistant skill system
|
|
|
6
6
|
|
|
7
7
|
Skills extend the assistant's capabilities by providing instructions (via `SKILL.md`) and optional custom tools (via `TOOLS.json`). Skills can be **bundled** (shipped with the application), **managed** (user-installed via `scaffold_managed_skill`), **workspace** (project-local), or **extra** (additional directories configured by the user).
|
|
8
8
|
|
|
9
|
-
For managed skills, the installed source of truth is a valid directory at
|
|
9
|
+
For managed skills, the installed source of truth is a valid directory at `$VELLUM_WORKSPACE_DIR/skills/<id>/` containing a top-level `SKILL.md` with standardized frontmatter. The assistant parses that frontmatter at startup and when skill directories change, then seeds Memory V2 skill entries under `skills/<id>` so the assistant can discover available skills from memory. The legacy `SKILLS.md` index is removed by workspace migration and is no longer created by install or scaffold paths.
|
|
10
10
|
|
|
11
11
|
Because skills can introduce arbitrary tool behavior, they are subject to stricter permission defaults than core tools.
|
|
12
12
|
|
|
@@ -70,7 +70,7 @@ Version-specific rules are more secure but require re-approval after every skill
|
|
|
70
70
|
|
|
71
71
|
Writing to skill source files is treated as a **high-risk** operation by the risk classifier. The `isSkillSourcePath()` function detects whether a file path falls under any known skill directory:
|
|
72
72
|
|
|
73
|
-
- **Managed skills**:
|
|
73
|
+
- **Managed skills**: `$VELLUM_WORKSPACE_DIR/skills/`
|
|
74
74
|
- **Bundled skills**: The application's built-in `bundled-skills/` directory
|
|
75
75
|
- **Workspace skills**: Project-local skill directories
|
|
76
76
|
- **Extra skills**: Additional roots configured by the user
|
|
@@ -116,10 +116,10 @@ Acceptance is idempotent and recorded in `trust.json`. The bundle does not inclu
|
|
|
116
116
|
|
|
117
117
|
Tools can execute in two contexts:
|
|
118
118
|
|
|
119
|
-
| Target | Description
|
|
120
|
-
| --------- |
|
|
121
|
-
| `sandbox` | Isolated execution within
|
|
122
|
-
| `host` | Direct execution on the host machine
|
|
119
|
+
| Target | Description |
|
|
120
|
+
| --------- | ---------------------------------------------------------------------------------------- |
|
|
121
|
+
| `sandbox` | Isolated execution within `$VELLUM_WORKSPACE_DIR` (Docker container or OS-level sandbox) |
|
|
122
|
+
| `host` | Direct execution on the host machine |
|
|
123
123
|
|
|
124
124
|
Trust rules can include an `executionTarget` field to bind the rule to a specific context. A rule without `executionTarget` matches both sandbox and host invocations.
|
|
125
125
|
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Workflows — Manual e2e / Live-Verification Runbook
|
|
2
|
+
|
|
3
|
+
This runbook covers the parts of the workflow engine that automated tests do not:
|
|
4
|
+
real provider calls, real journaled resume across a restart, capability
|
|
5
|
+
containment under a live model, flag-off inertness, and persona-leaf voice. Unit
|
|
6
|
+
and integration coverage lives under `assistant/src/workflows/*.test.ts` and
|
|
7
|
+
`assistant/src/__tests__/`; this is the human-in-the-loop pass that runs **last**,
|
|
8
|
+
on throwaway instances first, and only touches a real inbox or a production
|
|
9
|
+
instance at the very end.
|
|
10
|
+
|
|
11
|
+
Work through the steps in order. The `workflows` flag is **off by default**, so
|
|
12
|
+
every step that exercises the engine first enables it on a throwaway instance.
|
|
13
|
+
|
|
14
|
+
> **Safety rule:** Nothing in this runbook touches a real inbox, a real workspace,
|
|
15
|
+
> or a production instance until every throwaway-instance step has passed. The
|
|
16
|
+
> production/persona instance is the **last** step.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Hatch a throwaway instance and enable the flag
|
|
21
|
+
|
|
22
|
+
Hatch a disposable Docker instance built from local source:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
vellum hatch --remote docker --source .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Note the instance name it prints (e.g. `vellum-<adjective>-<animal>`). Use it as
|
|
29
|
+
`--assistant <name>` for everything below, or set it active.
|
|
30
|
+
|
|
31
|
+
Enable the `workflows` flag via that instance's feature-flag override file. The
|
|
32
|
+
override lives in the instance's `protected/feature-flags.json` (overrides here
|
|
33
|
+
win over the registry default — see the feature-flag-overrides gotcha):
|
|
34
|
+
|
|
35
|
+
```jsonc
|
|
36
|
+
// .../<instance>/protected/feature-flags.json
|
|
37
|
+
{ "workflows": true }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Restart the instance so it re-reads the override, then confirm it is up:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
vellum ps
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Sanity-check that the surface is now live: `vellum workflows runs --assistant <name>`
|
|
47
|
+
should return an (empty) table rather than a 404.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 2. Synthetic-corpus run (no Gmail/Slack dependency)
|
|
52
|
+
|
|
53
|
+
Drive a `run_workflow` over a **fixture item list passed as `args`** — no external
|
|
54
|
+
integration. Ask the assistant (via `vellum events`-visible conversation, the app,
|
|
55
|
+
or a CLI message) to run a small workflow such as the triage example from
|
|
56
|
+
[`workflows.md`](./workflows.md), passing a dozen synthetic items in `args.items`.
|
|
57
|
+
|
|
58
|
+
Watch the run:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
vellum workflows runs --assistant <name> # find the runId
|
|
62
|
+
vellum workflows show <run-id> --assistant <name> # status + agent/token counts
|
|
63
|
+
vellum events --assistant <name> # workflow_progress / workflow_completed
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Confirm:
|
|
67
|
+
|
|
68
|
+
- The run reaches `completed`.
|
|
69
|
+
- `agentsSpawned` matches the number of leaves the script should have launched.
|
|
70
|
+
- A completion summary is injected back into the originating conversation.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 3. Inspect the evidence
|
|
75
|
+
|
|
76
|
+
Query the instance's database directly (the live DB is under the instance's
|
|
77
|
+
`workspace/data/db/assistant.db`).
|
|
78
|
+
|
|
79
|
+
**Leaf cost attribution** — confirm leaves ran on the cost-optimized model and
|
|
80
|
+
tally spend:
|
|
81
|
+
|
|
82
|
+
```sql
|
|
83
|
+
SELECT model, COUNT(*) AS calls,
|
|
84
|
+
SUM(input_tokens) AS in_tok,
|
|
85
|
+
SUM(output_tokens) AS out_tok,
|
|
86
|
+
SUM(estimated_cost_usd) AS usd
|
|
87
|
+
FROM llm_usage_events
|
|
88
|
+
WHERE call_site = 'workflowLeaf'
|
|
89
|
+
GROUP BY model;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Request shape** — confirm the schema path forced a tool and used a cheap model;
|
|
93
|
+
for persona leaves, confirm identity + memory were injected:
|
|
94
|
+
|
|
95
|
+
```sql
|
|
96
|
+
SELECT id, created_at
|
|
97
|
+
FROM llm_request_logs
|
|
98
|
+
ORDER BY created_at DESC
|
|
99
|
+
LIMIT 20;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Inspect a few `request_payload` bodies:
|
|
103
|
+
|
|
104
|
+
- A **schema** leaf request carries `tool_choice` forcing the synthetic
|
|
105
|
+
`emit_result` tool and a cheap model id.
|
|
106
|
+
- A **persona** leaf request's system prompt carries the assistant identity and a
|
|
107
|
+
`<memory>` block; an **anonymous** leaf's does not.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 4. Restart-resume (journal replay)
|
|
112
|
+
|
|
113
|
+
Start a **long** synthetic run (enough leaves that it is still in flight for a few
|
|
114
|
+
seconds). While it is running, restart the assistant with **SIGTERM**:
|
|
115
|
+
|
|
116
|
+
> **Never SIGKILL the assistant.** SIGKILL leaves WAL pages unmerged and forces a
|
|
117
|
+
> costly recovery on the next start (and can corrupt an in-flight run). Use a
|
|
118
|
+
> graceful stop / `vellum sleep` / SIGTERM with grace.
|
|
119
|
+
|
|
120
|
+
After restart, the run that was in flight when the process stopped is no longer
|
|
121
|
+
`running` — at startup the assistant reconciles every orphaned `running` row to
|
|
122
|
+
`interrupted` (status only; the accounting counters are preserved). Resume is
|
|
123
|
+
**not automatic**. Confirm the run shows up as interrupted, then trigger an
|
|
124
|
+
explicit resume:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# The crashed run is now interrupted, not running.
|
|
128
|
+
vellum workflows runs --status interrupted
|
|
129
|
+
|
|
130
|
+
# Trigger the resume (or: manage_workflows with action="resume" from chat).
|
|
131
|
+
vellum workflows resume <run-id>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Resuming re-invokes the engine with the **same `runId`**, so the completed prefix
|
|
135
|
+
replays from the journal. Assert:
|
|
136
|
+
|
|
137
|
+
- Resuming does **not** double the `agentsSpawned` count or the
|
|
138
|
+
`llm_usage_events` rows for `call_site = 'workflowLeaf'` — the completed prefix
|
|
139
|
+
replays from the journal rather than re-spawning leaves. The agent count
|
|
140
|
+
**carries** across the restart (it seeds from the persisted run row) instead of
|
|
141
|
+
resetting to zero.
|
|
142
|
+
- Only leaves that had not completed before the restart produce new usage rows.
|
|
143
|
+
- The run transitions `interrupted` → `running` → a terminal status.
|
|
144
|
+
|
|
145
|
+
```sql
|
|
146
|
+
-- Before and after the resume, this count should not grow for already-done leaves.
|
|
147
|
+
SELECT COUNT(*) FROM llm_usage_events WHERE call_site = 'workflowLeaf';
|
|
148
|
+
|
|
149
|
+
-- The journal holds one row per completed (run_id, seq); resuming does not duplicate them.
|
|
150
|
+
SELECT run_id, COUNT(*) FROM workflow_journal GROUP BY run_id;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 5. Capability containment
|
|
156
|
+
|
|
157
|
+
Author a workflow whose leaf tries to use a **side-effecting tool that is absent
|
|
158
|
+
from its manifest** (e.g. a leaf prompt that pushes the model toward `file_write`
|
|
159
|
+
or a send tool, with `capabilities.tools` left empty). Run it and confirm:
|
|
160
|
+
|
|
161
|
+
- The forbidden tool invocation is **hard-denied** inside the leaf — it never
|
|
162
|
+
executes. The leaf gets an error result, not a permission prompt (there are no
|
|
163
|
+
per-call prompts inside a run).
|
|
164
|
+
- Declaring a **forbidden** tool (`subagent_spawn`, `run_workflow`,
|
|
165
|
+
`manage_workflows`, `manage_secure_command_tool`) in `capabilities.tools` fails
|
|
166
|
+
the run synchronously at start — `run_workflow` returns an error and **no**
|
|
167
|
+
`running` row is created.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 6. Flag-off inertness
|
|
172
|
+
|
|
173
|
+
On a **default** instance (no `workflows` override, or set back to `false` and
|
|
174
|
+
restart), confirm the whole surface is gone:
|
|
175
|
+
|
|
176
|
+
- `run_workflow` and `manage_workflows` are **absent** from the tool set (the
|
|
177
|
+
assistant cannot call them).
|
|
178
|
+
- The routes 404:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
vellum workflows runs --assistant <default-instance> # request fails (404)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- A scheduler `workflow`-mode job is **rejected** (the engine gate throws before
|
|
185
|
+
any run is launched).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 7. Real-data smoke (throwaway TEST account)
|
|
190
|
+
|
|
191
|
+
Only after steps 1–6 pass: run the full path against a **throwaway TEST Google or
|
|
192
|
+
Slack account** with about a dozen messages — never a real account. Drive the
|
|
193
|
+
end-to-end flow:
|
|
194
|
+
|
|
195
|
+
1. The assistant enumerates the relevant skill (e.g. `gmail`).
|
|
196
|
+
2. It authors and launches a `run_workflow` over the real messages.
|
|
197
|
+
3. Leaves synthesize results.
|
|
198
|
+
4. Any side-effecting action (label, draft, reply) goes through the declared
|
|
199
|
+
capability manifest and the normal audited-action path.
|
|
200
|
+
|
|
201
|
+
Confirm the run completes, the evidence queries from step 3 look right against
|
|
202
|
+
real content, and every side effect was one the manifest declared.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 8. Production / persona instance — LAST
|
|
207
|
+
|
|
208
|
+
Flip the `workflows` flag on a real (e.g. persona) instance **only after** the
|
|
209
|
+
throwaway instances above pass, and only after the instance is on current code:
|
|
210
|
+
|
|
211
|
+
1. `git pull` and **restart** the instance so it runs the merged code (a restart
|
|
212
|
+
alone re-runs stale code — see the deploy gotcha).
|
|
213
|
+
2. Enable the flag and restart.
|
|
214
|
+
3. Start with the **smallest real slice** — a few items, dry-run actions where the
|
|
215
|
+
tool supports it — before any larger or side-effecting run.
|
|
216
|
+
4. **Human-eval the persona-leaf voice**: read a persona leaf's output and confirm
|
|
217
|
+
it reads as the assistant, not as a generic worker.
|
|
218
|
+
|
|
219
|
+
Stop and reassess if any run's `agentsSpawned` approaches `maxAgentsPerRun`, if
|
|
220
|
+
spend (step 3 query) is higher than expected, or if any side effect was not one
|
|
221
|
+
the manifest declared.
|