@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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workflows
|
|
3
|
+
description: Author and run autonomous multi-agent workflows that fan work across parallel leaf agents
|
|
4
|
+
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
+
metadata:
|
|
6
|
+
emoji: "⚙️"
|
|
7
|
+
vellum:
|
|
8
|
+
display-name: "Workflows"
|
|
9
|
+
category: "system"
|
|
10
|
+
feature-flag: "workflows"
|
|
11
|
+
activation-hints:
|
|
12
|
+
- "A task decomposes into many similar sub-tasks that can run concurrently (score every item, extract a field from each of many documents, draft-then-verify a batch)"
|
|
13
|
+
- "You want fan-out orchestrated deterministically and the result reported back when the whole run finishes"
|
|
14
|
+
avoid-when:
|
|
15
|
+
- "The task is a single tool call or a quick lookup — do it inline"
|
|
16
|
+
- "The work needs interactive, conversational back-and-forth rather than unattended fan-out"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
A workflow is a short JS/TS script you author that runs in a sandbox and fans work
|
|
20
|
+
out across many short-lived **leaf agents**, orchestrated deterministically. Launch
|
|
21
|
+
one with `run_workflow` (inline `script` OR saved `name`, exactly one). It returns a
|
|
22
|
+
`runId` immediately; the run is asynchronous and you are notified in this
|
|
23
|
+
conversation when it completes — **do NOT poll**.
|
|
24
|
+
|
|
25
|
+
Reach for one when a task decomposes into many similar small sub-tasks that can run
|
|
26
|
+
concurrently. For a single task or a quick lookup, do it inline.
|
|
27
|
+
|
|
28
|
+
## The script model
|
|
29
|
+
|
|
30
|
+
These are the load-bearing invariants. Get them wrong and the run misbehaves silently.
|
|
31
|
+
|
|
32
|
+
### Scripts are SYNCHRONOUS — never `await`
|
|
33
|
+
|
|
34
|
+
Host functions block and return their result directly. Write straight-line code.
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
const r = agent("Summarize this thread."); // r is the result, right here
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Do **not** write `await agent(...)`, and do **not** make the script `async`. An
|
|
41
|
+
`async` script deadlocks on its second host call — the sandbox can suspend the main
|
|
42
|
+
evaluation stack but not a promise continuation.
|
|
43
|
+
|
|
44
|
+
### Every script begins with a literal `meta`
|
|
45
|
+
|
|
46
|
+
The first statement must be a pure-literal export — no computed values, template
|
|
47
|
+
strings, or concatenation:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
export const meta = {
|
|
51
|
+
name: "triage-inbox",
|
|
52
|
+
description: "Triage and label inbox messages",
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`meta` is extracted **statically**, without executing the script, so it must be a
|
|
57
|
+
plain object literal with string `name` and `description`. The `name` is how a saved
|
|
58
|
+
workflow is referenced by `workflow(name)` and the scheduler.
|
|
59
|
+
|
|
60
|
+
### You must `return` the result
|
|
61
|
+
|
|
62
|
+
The script body runs as a function. Its result is whatever it `return`s at the top
|
|
63
|
+
level — a bare trailing expression (e.g. `result;`) is **discarded** and the run
|
|
64
|
+
finishes with no result. Always `return` the value you want surfaced.
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const result = agent(`Write the final summary: ${JSON.stringify(parts)}`);
|
|
68
|
+
return result;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Determinism (this is what makes runs resumable)
|
|
72
|
+
|
|
73
|
+
Every leaf call is journaled by sequence number and input hash, so a resumed run can
|
|
74
|
+
replay the unchanged prefix instead of re-spawning agents. That only holds if the
|
|
75
|
+
script is deterministic, so `Date.now()`, `Math.random()`, and argless `new Date()`
|
|
76
|
+
**throw**. Pass any timestamps or random seeds in through `args`.
|
|
77
|
+
|
|
78
|
+
## Host API
|
|
79
|
+
|
|
80
|
+
All functions are synchronous from the script's perspective.
|
|
81
|
+
|
|
82
|
+
| Function | Returns | Notes |
|
|
83
|
+
| ---------------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `agent(prompt, opts?)` | the leaf's result | Runs ONE leaf. **Throws** on leaf failure (fails the whole run). |
|
|
85
|
+
| `leaf(prompt, opts?)` | a leaf descriptor | Runs nothing on its own; used inside `parallel`/`map`/`pipeline`. |
|
|
86
|
+
| `parallel(specs)` | `results[]` | Runs an array of `leaf(...)` descriptors concurrently, results in input order. A failed leaf becomes `null` (never throws). |
|
|
87
|
+
| `map(items, build)` | `results[]` | `build(item, i)` returns a `leaf(...)` descriptor per item; runs them like `parallel`. |
|
|
88
|
+
| `pipeline(items, ...stages)` | `results[]` | Each `stage(prev, i)` returns a `leaf(...)` descriptor (run an agent) OR a plain value (pass through unchanged — filter/transform locally, no agent spent). Per-stage barrier: stage N+1 starts only after all of stage N finishes. |
|
|
89
|
+
| `phase(title)` | — | Marks a named phase for progress reporting. |
|
|
90
|
+
| `log(msg)` | — | Emits a progress log line. |
|
|
91
|
+
| `usage()` | `{ agentsSpawned, inputTokens, outputTokens }` | Live snapshot so a script can self-moderate. |
|
|
92
|
+
| `workflow(name, args?)` | the child's result | Runs a SAVED workflow inline, depth 1 only (a child may not call `workflow()`). |
|
|
93
|
+
| `args` | the run input | The `args` object passed to `run_workflow`. |
|
|
94
|
+
|
|
95
|
+
Use `agent` for a single sequential leaf (throws on failure). Use `parallel`/`map`/
|
|
96
|
+
`pipeline` for fan-out (a failed leaf is `null`, so a batch survives a few bad items).
|
|
97
|
+
|
|
98
|
+
## Leaf options (`opts` for `agent` / `leaf`)
|
|
99
|
+
|
|
100
|
+
| Option | Type | Effect |
|
|
101
|
+
| --------- | -------------------------- | --------------------------------------------------------------------------------------- |
|
|
102
|
+
| `schema` | JSON Schema object literal | Forces structured output via a tool. A schema leaf runs with **no tools** (pure judge/extractor). Use a plain JSON Schema literal, not Zod. |
|
|
103
|
+
| `label` | string | Short display/diagnostic label for the leaf. |
|
|
104
|
+
| `profile` | string | Overrides the model profile. Must exist in `llm.profiles` or the leaf throws. See [Listing profiles](#listing-available-profiles). |
|
|
105
|
+
| `persona` | boolean | `true` makes the leaf speak AS the assistant (identity + memory) — use for output meant to be in the assistant's voice. Default is anonymous — use for impartial judging/extraction. |
|
|
106
|
+
|
|
107
|
+
`persona: true` is the costly path (it runs the full memory-injection pipeline). Use
|
|
108
|
+
it only for the few leaves whose output must be in the assistant's voice; keep bulk
|
|
109
|
+
judging/extraction anonymous.
|
|
110
|
+
|
|
111
|
+
## Capabilities — the single consent point
|
|
112
|
+
|
|
113
|
+
The `capabilities` argument to `run_workflow` declares **once**, up front, what the
|
|
114
|
+
run's leaves may do. There are **no per-call permission prompts inside a running
|
|
115
|
+
workflow**.
|
|
116
|
+
|
|
117
|
+
```jsonc
|
|
118
|
+
{
|
|
119
|
+
"tools": ["file_write", "gmail_send"], // side-effecting tools granted to leaves
|
|
120
|
+
"hostFunctions": [], // host-function names the run may invoke
|
|
121
|
+
"persona": true // grant leaves persona (identity + memory)
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- **Read-only baseline** (always available, no declaration, no launch prompt):
|
|
126
|
+
`file_read`, `file_list`, `recall`, `web_search`.
|
|
127
|
+
- **`web_fetch` is NOT in the baseline** — an outbound fetch is side-effecting (its
|
|
128
|
+
URL can exfiltrate read data), so a leaf that must fetch a URL has to declare
|
|
129
|
+
`"web_fetch"` in `capabilities.tools`.
|
|
130
|
+
- **Declaring ANY side-effecting tool** (writes, sends, shell, `web_fetch`, …) or
|
|
131
|
+
host function makes the LAUNCH prompt the user for approval **once** — that single
|
|
132
|
+
approval covers the whole run. A read-only run (no declared tools) launches with no
|
|
133
|
+
prompt. Declare the minimum you need.
|
|
134
|
+
|
|
135
|
+
Runs are autonomous but BOUNDED by a per-run agent cap — spend is structurally
|
|
136
|
+
capped and you cannot exceed it.
|
|
137
|
+
|
|
138
|
+
## Listing available profiles
|
|
139
|
+
|
|
140
|
+
Before choosing a `profile` for a leaf, look up the valid values rather than guessing
|
|
141
|
+
— an unknown profile throws.
|
|
142
|
+
|
|
143
|
+
- **Preferred (model-accessible):** call `manage_workflows` with action
|
|
144
|
+
`list_profiles`. It returns the profile names defined in `llm.profiles` plus the
|
|
145
|
+
workspace-wide active profile.
|
|
146
|
+
- The same data is served by the daemon route `GET config/llm/profiles` (operationId
|
|
147
|
+
`llm_profiles_list`), which clients use to populate profile dropdowns.
|
|
148
|
+
|
|
149
|
+
Omit `profile` to use the default: a persona leaf mirrors the main agent (the active
|
|
150
|
+
profile floats above the call-site default); an anonymous leaf uses the cost-optimized
|
|
151
|
+
`workflowLeaf` default.
|
|
152
|
+
|
|
153
|
+
## Run management
|
|
154
|
+
|
|
155
|
+
Use `manage_workflows` to inspect and control runs:
|
|
156
|
+
|
|
157
|
+
| Action | Requires | Purpose |
|
|
158
|
+
| --------------- | ---------- | ---------------------------------------------------------------- |
|
|
159
|
+
| `status` | `run_id` | Status + agent/token counts for one run (NOT the result). |
|
|
160
|
+
| `get_result` | `run_id` | The full result of a finished run. |
|
|
161
|
+
| `list_runs` | — | Recent runs, newest first. |
|
|
162
|
+
| `abort` | `run_id` | Signal an in-flight run to abort. |
|
|
163
|
+
| `resume` | `run_id` | Resume an `interrupted` run (see below). |
|
|
164
|
+
| `list_profiles` | — | List defined profiles + the active profile (for leaf `profile`).|
|
|
165
|
+
|
|
166
|
+
The completion notification injected when a run finishes carries a **truncated**
|
|
167
|
+
preview of the result (large results are cut off). To read the complete result,
|
|
168
|
+
call `manage_workflows` with action `get_result` and the `run_id` — `status`
|
|
169
|
+
deliberately omits the result to stay lightweight.
|
|
170
|
+
|
|
171
|
+
### Crash recovery / resume
|
|
172
|
+
|
|
173
|
+
Resume is **not automatic**. If the assistant restarts mid-run, the run is reconciled
|
|
174
|
+
to status `interrupted` (the agent/token accounting is preserved so the agent cap
|
|
175
|
+
still carries across the restart). It sits there until you explicitly resume it by
|
|
176
|
+
`run_id` via `manage_workflows` action `resume`. Resuming re-invokes the engine with
|
|
177
|
+
the same `runId`: the journal **replays the completed prefix** without re-spawning (or
|
|
178
|
+
re-paying for) finished leaves, then continues from the first unfinished leaf under the
|
|
179
|
+
run's originally-declared capabilities. Only `interrupted` runs are resumable; a
|
|
180
|
+
`completed` / `failed` / `aborted` run is terminal.
|
|
181
|
+
|
|
182
|
+
## Worked example
|
|
183
|
+
|
|
184
|
+
Score each inbox item in parallel (anonymous schema leaves), then write one summary in
|
|
185
|
+
the assistant's voice (a single persona leaf). The item list comes in via `args` —
|
|
186
|
+
never fetched inside the script.
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
export const meta = {
|
|
190
|
+
name: "triage-inbox",
|
|
191
|
+
description: "Score and summarize inbox items",
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
phase("score");
|
|
195
|
+
const scored = map(args.items, (item) =>
|
|
196
|
+
leaf(`Rate this message's urgency 0-10 with a one-line reason:\n${item.subject}\n${item.body}`, {
|
|
197
|
+
label: `score:${item.id}`,
|
|
198
|
+
schema: {
|
|
199
|
+
type: "object",
|
|
200
|
+
properties: { urgency: { type: "number" }, reason: { type: "string" } },
|
|
201
|
+
required: ["urgency", "reason"],
|
|
202
|
+
},
|
|
203
|
+
}),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
phase("summarize");
|
|
207
|
+
const summary = agent(
|
|
208
|
+
`Here are scored inbox items. Write a short triage summary, highlighting anything urgent:\n${JSON.stringify(scored)}`,
|
|
209
|
+
{ persona: true },
|
|
210
|
+
);
|
|
211
|
+
return summary;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
A failed scoring leaf shows up as `null` in `scored`; the run continues.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"tools": [
|
|
4
|
+
{
|
|
5
|
+
"name": "run_workflow",
|
|
6
|
+
"description": "Launch an autonomous, multi-agent workflow from a script you author (or by saved name); returns a runId immediately and notifies this conversation on completion. See SKILL.md for the full script-authoring contract.",
|
|
7
|
+
"category": "workflow",
|
|
8
|
+
"risk": "low",
|
|
9
|
+
"input_schema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"script": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Inline workflow source (JavaScript/TypeScript) following the authoring contract. Provide this OR name, not both."
|
|
15
|
+
},
|
|
16
|
+
"name": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Name of a previously saved workflow to run. Provide this OR script, not both."
|
|
19
|
+
},
|
|
20
|
+
"args": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"description": "Verbatim input object exposed to the script as `args`. Pass timestamps/seeds here (the script may not generate them)."
|
|
23
|
+
},
|
|
24
|
+
"capabilities": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"description": "Per-run capability grant (the single consent point). Leaves get a read-only baseline by default.",
|
|
27
|
+
"properties": {
|
|
28
|
+
"tools": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"items": { "type": "string" },
|
|
31
|
+
"description": "Side-effecting tool names granted to leaves on top of the read-only baseline."
|
|
32
|
+
},
|
|
33
|
+
"hostFunctions": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": { "type": "string" },
|
|
36
|
+
"description": "Host-function names the run may invoke."
|
|
37
|
+
},
|
|
38
|
+
"persona": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"description": "Grant leaves access to persona (identity + memory) context."
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"label": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "Human-readable label for display; defaults to the script's meta.name."
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"executor": "tools/run-workflow.ts",
|
|
51
|
+
"execution_target": "host"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "manage_workflows",
|
|
55
|
+
"description": "Inspect or control workflow runs started by run_workflow: status, get_result (the full result of a finished run — the completion notification truncates large results), abort, resume, list_runs, and list_profiles. See SKILL.md for details.",
|
|
56
|
+
"category": "workflow",
|
|
57
|
+
"risk": "low",
|
|
58
|
+
"input_schema": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"action": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"enum": [
|
|
64
|
+
"status",
|
|
65
|
+
"get_result",
|
|
66
|
+
"abort",
|
|
67
|
+
"resume",
|
|
68
|
+
"list_runs",
|
|
69
|
+
"list_profiles"
|
|
70
|
+
],
|
|
71
|
+
"description": "What to do."
|
|
72
|
+
},
|
|
73
|
+
"run_id": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"description": "Target run id (required for \"status\", \"get_result\", \"abort\", and \"resume\")."
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"required": ["action"]
|
|
79
|
+
},
|
|
80
|
+
"executor": "tools/manage-workflows.ts",
|
|
81
|
+
"execution_target": "host"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ToolContext,
|
|
3
|
+
ToolExecutionResult,
|
|
4
|
+
} from "../../../../tools/types.js";
|
|
5
|
+
import { executeManageWorkflows } from "../../../../tools/workflows/manage-workflows.js";
|
|
6
|
+
|
|
7
|
+
export async function run(
|
|
8
|
+
input: Record<string, unknown>,
|
|
9
|
+
context: ToolContext,
|
|
10
|
+
): Promise<ToolExecutionResult> {
|
|
11
|
+
return executeManageWorkflows(input, context);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ToolContext,
|
|
3
|
+
ToolExecutionResult,
|
|
4
|
+
} from "../../../../tools/types.js";
|
|
5
|
+
import { executeRunWorkflow } from "../../../../tools/workflows/run-workflow.js";
|
|
6
|
+
|
|
7
|
+
export async function run(
|
|
8
|
+
input: Record<string, unknown>,
|
|
9
|
+
context: ToolContext,
|
|
10
|
+
): Promise<ToolExecutionResult> {
|
|
11
|
+
return executeRunWorkflow(input, context);
|
|
12
|
+
}
|
|
@@ -24,7 +24,7 @@ import * as appCreate from "./bundled-skills/app-builder/tools/app-create.js";
|
|
|
24
24
|
import * as appDelete from "./bundled-skills/app-builder/tools/app-delete.js";
|
|
25
25
|
import * as appGenerateIcon from "./bundled-skills/app-builder/tools/app-generate-icon.js";
|
|
26
26
|
import * as appList from "./bundled-skills/app-builder/tools/app-list.js";
|
|
27
|
-
import * as
|
|
27
|
+
import * as appBuilder_appRefresh from "./bundled-skills/app-builder/tools/app-refresh.js";
|
|
28
28
|
import * as appUpdate from "./bundled-skills/app-builder/tools/app-update.js";
|
|
29
29
|
// ── app-control ────────────────────────────────────────────────────────────────
|
|
30
30
|
import * as appControlClick from "./bundled-skills/app-control/tools/app-control-click.js";
|
|
@@ -88,6 +88,8 @@ import * as messagingRead from "./bundled-skills/messaging/tools/messaging-read.
|
|
|
88
88
|
import * as messagingSearch from "./bundled-skills/messaging/tools/messaging-search.js";
|
|
89
89
|
import * as messagingSend from "./bundled-skills/messaging/tools/messaging-send.js";
|
|
90
90
|
import * as messagingSenderDigest from "./bundled-skills/messaging/tools/messaging-sender-digest.js";
|
|
91
|
+
// ── personal-page ──────────────────────────────────────────────────────────────
|
|
92
|
+
import * as personalPage_appRefresh from "./bundled-skills/personal-page/tools/app-refresh.js";
|
|
91
93
|
// ── phone-calls ────────────────────────────────────────────────────────────────
|
|
92
94
|
import * as callEnd from "./bundled-skills/phone-calls/tools/call-end.js";
|
|
93
95
|
import * as callStart from "./bundled-skills/phone-calls/tools/call-start.js";
|
|
@@ -127,6 +129,9 @@ import * as subagentSpawn from "./bundled-skills/subagent/tools/subagent-spawn.j
|
|
|
127
129
|
import * as subagentStatus from "./bundled-skills/subagent/tools/subagent-status.js";
|
|
128
130
|
// ── transcribe ─────────────────────────────────────────────────────────────────
|
|
129
131
|
import * as transcribeMedia from "./bundled-skills/transcribe/tools/transcribe-media.js";
|
|
132
|
+
// ── workflows ──────────────────────────────────────────────────────────────────
|
|
133
|
+
import * as manageWorkflows from "./bundled-skills/workflows/tools/manage-workflows.js";
|
|
134
|
+
import * as runWorkflow from "./bundled-skills/workflows/tools/run-workflow.js";
|
|
130
135
|
|
|
131
136
|
// ─── Registry ────────────────────────────────────────────────────────────────
|
|
132
137
|
|
|
@@ -143,7 +148,7 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
|
|
|
143
148
|
["app-builder:tools/app-create.ts", appCreate],
|
|
144
149
|
["app-builder:tools/app-update.ts", appUpdate],
|
|
145
150
|
["app-builder:tools/app-delete.ts", appDelete],
|
|
146
|
-
["app-builder:tools/app-refresh.ts",
|
|
151
|
+
["app-builder:tools/app-refresh.ts", appBuilder_appRefresh],
|
|
147
152
|
["app-builder:tools/app-generate-icon.ts", appGenerateIcon],
|
|
148
153
|
["app-builder:tools/app-list.ts", appList],
|
|
149
154
|
|
|
@@ -223,6 +228,9 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
|
|
|
223
228
|
["messaging:tools/messaging-sender-digest.ts", messagingSenderDigest],
|
|
224
229
|
["messaging:tools/messaging-archive-by-sender.ts", messagingArchiveBySender],
|
|
225
230
|
|
|
231
|
+
// personal-page
|
|
232
|
+
["personal-page:tools/app-refresh.ts", personalPage_appRefresh],
|
|
233
|
+
|
|
226
234
|
// phone-calls
|
|
227
235
|
["phone-calls:tools/call-start.ts", callStart],
|
|
228
236
|
["phone-calls:tools/call-status.ts", callStatus],
|
|
@@ -269,4 +277,8 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
|
|
|
269
277
|
|
|
270
278
|
// transcribe
|
|
271
279
|
["transcribe:tools/transcribe-media.ts", transcribeMedia],
|
|
280
|
+
|
|
281
|
+
// workflows
|
|
282
|
+
["workflows:tools/run-workflow.ts", runWorkflow],
|
|
283
|
+
["workflows:tools/manage-workflows.ts", manageWorkflows],
|
|
272
284
|
]);
|
|
@@ -125,4 +125,9 @@ export const CALL_SITE_DEFAULTS: Record<LLMCallSite, CallSiteDefaultConfig> = {
|
|
|
125
125
|
thinking: { enabled: false },
|
|
126
126
|
disableCache: true,
|
|
127
127
|
},
|
|
128
|
+
workflowLeaf: {
|
|
129
|
+
profile: "cost-optimized",
|
|
130
|
+
effort: "low",
|
|
131
|
+
thinking: { enabled: false },
|
|
132
|
+
},
|
|
128
133
|
};
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"scope": "assistant",
|
|
15
15
|
"key": "memory-retrospective-fork",
|
|
16
16
|
"label": "Fork-based memory retrospective",
|
|
17
|
-
"description": "Fork the source conversation through its latest message for memory retrospectives, instead of rendering the slice into a transcript and waking an empty background conversation.
|
|
17
|
+
"description": "Fork the source conversation through its latest message for memory retrospectives, instead of rendering the slice into a transcript and waking an empty background conversation. The retrospective reads the conversation natively, including any inherited compaction summary and tail messages. Provider prompt-cache reuse additionally requires memory.retrospective.matchConversationProfile.",
|
|
18
18
|
"defaultEnabled": false
|
|
19
19
|
},
|
|
20
20
|
{
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"id": "experiment-activation-flow-2026-06-03",
|
|
39
|
-
"scope": "
|
|
39
|
+
"scope": "both",
|
|
40
40
|
"key": "experiment-activation-flow-2026-06-03",
|
|
41
41
|
"label": "Activation Flow Experiment 2026-06-03",
|
|
42
|
-
"description": "Multivariate activation-flow experiment. control = standard flow; variant-a = activation rail. Targeted via LaunchDarkly.",
|
|
42
|
+
"description": "Multivariate activation-flow experiment. control = standard flow; variant-a = activation rail; personal-page = preseeded personal-page app (read by the daemon, hence scope \"both\"). Targeted via LaunchDarkly.",
|
|
43
43
|
"defaultEnabled": "control",
|
|
44
|
-
"values": ["control", "variant-a"]
|
|
44
|
+
"values": ["control", "variant-a", "personal-page"]
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"id": "local-docker-enabled",
|
|
@@ -410,6 +410,14 @@
|
|
|
410
410
|
"label": "Self-intro first message",
|
|
411
411
|
"description": "On the first conversation, send a natural self-introduction (e.g. \"Hi Vela, I'm alex. Nice to meet you.\") on the user's behalf and route it through real LLM inference, instead of serving the canned first greeting. Names come from the onboarding context; falls back to the canned greeting when no name is known. Exposed to clients so pre-hatch onboarding can compute the source-of-truth initial message, and to the assistant so older clients can still be gated server-side. See assistant/src/daemon/first-greeting.ts (buildSelfIntroMessage).",
|
|
412
412
|
"defaultEnabled": false
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"id": "workflows",
|
|
416
|
+
"scope": "assistant",
|
|
417
|
+
"key": "workflows",
|
|
418
|
+
"label": "Assistant Workflows",
|
|
419
|
+
"description": "Enable the sandboxed workflow orchestration engine (script-driven parallel leaf agents).",
|
|
420
|
+
"defaultEnabled": false
|
|
413
421
|
}
|
|
414
422
|
]
|
|
415
423
|
}
|
|
@@ -27,11 +27,18 @@ export function resolveEffectiveContextWindow({
|
|
|
27
27
|
llm,
|
|
28
28
|
callSite,
|
|
29
29
|
overrideProfile,
|
|
30
|
+
forceOverrideProfile,
|
|
30
31
|
selectionSeed,
|
|
31
32
|
}: {
|
|
32
33
|
llm: LLMConfig;
|
|
33
34
|
callSite: LLMCallSite;
|
|
34
35
|
overrideProfile?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Float `overrideProfile` above the call-site layers (see
|
|
38
|
+
* `ResolveCallSiteOpts.forceOverrideProfile`). Threaded so context-window
|
|
39
|
+
* sizing reflects the same profile the dispatch path resolves.
|
|
40
|
+
*/
|
|
41
|
+
forceOverrideProfile?: boolean;
|
|
35
42
|
/**
|
|
36
43
|
* Per-conversation mix seed (the conversation id). Threaded so context-window
|
|
37
44
|
* sizing for a mix profile reflects the same arm the dispatch path picks.
|
|
@@ -40,6 +47,7 @@ export function resolveEffectiveContextWindow({
|
|
|
40
47
|
}): EffectiveContextWindow {
|
|
41
48
|
const resolved = resolveCallSiteConfig(callSite, llm, {
|
|
42
49
|
overrideProfile,
|
|
50
|
+
forceOverrideProfile,
|
|
43
51
|
selectionSeed,
|
|
44
52
|
});
|
|
45
53
|
const catalogModel = PROVIDER_CATALOG.find(
|
|
@@ -32,6 +32,19 @@ import {
|
|
|
32
32
|
* 4. `llm.profiles[llm.activeProfile]`
|
|
33
33
|
* 5. `llm.profiles[opts.overrideProfile]`
|
|
34
34
|
*
|
|
35
|
+
* `opts.forceOverrideProfile` is an explicit escape hatch for non-main-agent
|
|
36
|
+
* call sites: when true (and `opts.overrideProfile` resolves to a defined
|
|
37
|
+
* profile), the override profile floats ABOVE the call-site layers — the
|
|
38
|
+
* non-main ordering becomes default → activeProfile → site profile →
|
|
39
|
+
* call-site override → overrideProfile. This mirrors how `mainAgent` treats
|
|
40
|
+
* the user's chat-model selection as authoritative, and exists for callers
|
|
41
|
+
* that must run a background call site under a specific conversation's
|
|
42
|
+
* inference profile (e.g. fork-based memory retrospectives matching the
|
|
43
|
+
* source conversation for provider prompt-cache reuse). When the referenced
|
|
44
|
+
* profile is missing, the flag is inert and the normal precedence applies
|
|
45
|
+
* (same silent fall-through as any `overrideProfile` reference); for
|
|
46
|
+
* `mainAgent` the flag is a no-op because the override already sits on top.
|
|
47
|
+
*
|
|
35
48
|
* Nested objects (`thinking`, `contextWindow`, and
|
|
36
49
|
* `contextWindow.overflowRecovery`) are deep-merged so partial overrides at
|
|
37
50
|
* any nesting level merge into — rather than replace — the corresponding
|
|
@@ -54,6 +67,14 @@ import {
|
|
|
54
67
|
*/
|
|
55
68
|
export interface ResolveCallSiteOpts {
|
|
56
69
|
overrideProfile?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Float `overrideProfile` above the call-site layers (named site profile +
|
|
72
|
+
* call-site override) for non-main-agent call sites. See the
|
|
73
|
+
* `resolveCallSiteConfig` docstring for the resulting precedence and the
|
|
74
|
+
* use case. Inert when `overrideProfile` is absent or references a missing
|
|
75
|
+
* profile, and a no-op for `mainAgent`.
|
|
76
|
+
*/
|
|
77
|
+
forceOverrideProfile?: boolean;
|
|
57
78
|
/**
|
|
58
79
|
* Per-conversation seed for expanding `mix` profiles. The chosen constituent
|
|
59
80
|
* is a deterministic function of `selectionSeed` + the mix profile's own
|
|
@@ -101,6 +122,15 @@ export function resolveCallSiteConfig(
|
|
|
101
122
|
appendCallSiteLayers(layers, callSite, llm, site, opts, biasRef);
|
|
102
123
|
appendProfileLayer(layers, activeFragment, biasRef);
|
|
103
124
|
appendProfileLayer(layers, overrideFragment, biasRef);
|
|
125
|
+
} else if (opts.forceOverrideProfile === true && overrideFragment != null) {
|
|
126
|
+
// Escape hatch: float the override profile above the call-site layers,
|
|
127
|
+
// mirroring mainAgent's treatment of the user's chat-model selection.
|
|
128
|
+
// Guarded on a resolved fragment so a missing profile reference degrades
|
|
129
|
+
// to the normal precedence below instead of silently dropping the
|
|
130
|
+
// call-site layers' standing.
|
|
131
|
+
appendProfileLayer(layers, activeFragment, biasRef);
|
|
132
|
+
appendCallSiteLayers(layers, callSite, llm, site, opts, biasRef);
|
|
133
|
+
appendProfileLayer(layers, overrideFragment, biasRef);
|
|
104
134
|
} else {
|
|
105
135
|
appendProfileLayer(layers, activeFragment, biasRef);
|
|
106
136
|
appendProfileLayer(layers, overrideFragment, biasRef);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { profile } from "../profile-data";
|
|
2
|
+
import { AnimatedParagraph, WordsPullUpMultiStyle } from "./animations";
|
|
3
|
+
|
|
4
|
+
export function About() {
|
|
5
|
+
const { about } = profile;
|
|
6
|
+
return (
|
|
7
|
+
<section class="about" id="about">
|
|
8
|
+
<div class="about-card">
|
|
9
|
+
<div class="about-label">{about.label}</div>
|
|
10
|
+
<h2 class="about-heading">
|
|
11
|
+
<WordsPullUpMultiStyle
|
|
12
|
+
segments={about.heading.map((seg) => ({
|
|
13
|
+
text: seg.text,
|
|
14
|
+
className: seg.italic ? "serif-italic" : undefined,
|
|
15
|
+
}))}
|
|
16
|
+
/>
|
|
17
|
+
</h2>
|
|
18
|
+
<AnimatedParagraph className="about-body" text={about.body} />
|
|
19
|
+
</div>
|
|
20
|
+
</section>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { profile } from "../profile-data";
|
|
2
|
+
import { About } from "./About";
|
|
3
|
+
import { Features } from "./Features";
|
|
4
|
+
import { Hero } from "./Hero";
|
|
5
|
+
import { Pending } from "./Pending";
|
|
6
|
+
|
|
7
|
+
export function App() {
|
|
8
|
+
if (profile.status !== "ready") return <Pending />;
|
|
9
|
+
return (
|
|
10
|
+
<main>
|
|
11
|
+
<Hero />
|
|
12
|
+
<About />
|
|
13
|
+
<Features />
|
|
14
|
+
</main>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ComponentChildren } from "preact";
|
|
2
|
+
|
|
3
|
+
import { profile } from "../profile-data";
|
|
4
|
+
import { StaggerCard, WordsPullUpMultiStyle } from "./animations";
|
|
5
|
+
import { ArrowRight, Check } from "./icons";
|
|
6
|
+
import { CARD_ICONS } from "./media";
|
|
7
|
+
|
|
8
|
+
function CheckLine({ children }: { children: ComponentChildren }) {
|
|
9
|
+
return (
|
|
10
|
+
<li>
|
|
11
|
+
<Check className="check" />
|
|
12
|
+
<span>{children}</span>
|
|
13
|
+
</li>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function LearnMore() {
|
|
18
|
+
return (
|
|
19
|
+
<a class="learn-more">
|
|
20
|
+
Learn more
|
|
21
|
+
<ArrowRight size={14} />
|
|
22
|
+
</a>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function Features() {
|
|
27
|
+
const { features } = profile;
|
|
28
|
+
return (
|
|
29
|
+
<section class="features">
|
|
30
|
+
<div class="features-inner">
|
|
31
|
+
<div class="features-header">
|
|
32
|
+
<div>
|
|
33
|
+
<WordsPullUpMultiStyle
|
|
34
|
+
segments={[{ text: features.headingLine1, className: "line1" }]}
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
<div style={{ marginTop: "0.3em" }}>
|
|
38
|
+
<WordsPullUpMultiStyle
|
|
39
|
+
segments={[{ text: features.headingLine2, className: "line2" }]}
|
|
40
|
+
delayBase={0.2}
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="feature-grid">
|
|
46
|
+
<StaggerCard index={0} className="feature-card visual">
|
|
47
|
+
<div class="card-backdrop" />
|
|
48
|
+
<div class="vlabel">{features.statusLabel}</div>
|
|
49
|
+
</StaggerCard>
|
|
50
|
+
|
|
51
|
+
{features.cards.slice(0, 3).map((card, i) => (
|
|
52
|
+
<StaggerCard
|
|
53
|
+
index={i + 1}
|
|
54
|
+
className="feature-card"
|
|
55
|
+
id={`feature-${i}`}
|
|
56
|
+
key={card.title}
|
|
57
|
+
>
|
|
58
|
+
<img
|
|
59
|
+
class="feature-icon"
|
|
60
|
+
src={CARD_ICONS[i % CARD_ICONS.length]}
|
|
61
|
+
alt=""
|
|
62
|
+
/>
|
|
63
|
+
<div class="feature-num">{`0${i + 1}`}</div>
|
|
64
|
+
<div class="feature-title">{card.title}</div>
|
|
65
|
+
<ul class="feature-list">
|
|
66
|
+
{card.bullets.map((b) => (
|
|
67
|
+
<CheckLine key={b}>{b}</CheckLine>
|
|
68
|
+
))}
|
|
69
|
+
</ul>
|
|
70
|
+
<LearnMore />
|
|
71
|
+
</StaggerCard>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</section>
|
|
76
|
+
);
|
|
77
|
+
}
|