@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
|
@@ -23,11 +23,14 @@ import type { WorkspaceMigration } from "./types.js";
|
|
|
23
23
|
// - Are source: "user" (user-created profiles are untouched)
|
|
24
24
|
// - Have a non-managed, non-absent source (unknown origin)
|
|
25
25
|
// - Resolve to a non-Anthropic provider (adaptive thinking is
|
|
26
|
-
// Anthropic-specific).
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
26
|
+
// Anthropic-specific). Effective provider is the profile's explicit
|
|
27
|
+
// `provider`; otherwise the provider implied by a known Claude `model`
|
|
28
|
+
// (mirroring the resolver's withImpliedProviderForKnownModel); otherwise
|
|
29
|
+
// llm.default.provider — with a completely absent llm.default.provider
|
|
30
|
+
// treated as Anthropic, matching migration 052's own `?? "anthropic"`
|
|
31
|
+
// default. This keeps the legacy non-Anthropic empty `{}` shells seeded by
|
|
32
|
+
// migration 052 off the repair while still patching profiles that pin a
|
|
33
|
+
// known Claude model under a non-Anthropic default.
|
|
31
34
|
//
|
|
32
35
|
// Note: the live startup path re-runs the same repair after the platform
|
|
33
36
|
// overlay merge — see assistant/src/workspace/adaptive-thinking-repair.ts.
|
|
@@ -61,8 +64,9 @@ export const enableAdaptiveThinkingManagedProfilesMigration: WorkspaceMigration
|
|
|
61
64
|
const profiles = readObject(llm.profiles);
|
|
62
65
|
if (profiles === null) return;
|
|
63
66
|
|
|
64
|
-
// Profiles without an explicit provider
|
|
65
|
-
//
|
|
67
|
+
// Profiles without an explicit provider and without a model-implied
|
|
68
|
+
// provider inherit llm.default.provider at resolution time; an absent
|
|
69
|
+
// llm.default.provider resolves to Anthropic.
|
|
66
70
|
const defaultBlock = readObject(llm.default);
|
|
67
71
|
const defaultProvider =
|
|
68
72
|
typeof defaultBlock?.provider === "string"
|
|
@@ -79,17 +83,19 @@ export const enableAdaptiveThinkingManagedProfilesMigration: WorkspaceMigration
|
|
|
79
83
|
// Legacy profiles created before the `source` metadata field was
|
|
80
84
|
// introduced have source=undefined. Treat these as managed when the
|
|
81
85
|
// profile name is one of the canonical managed names (which
|
|
82
|
-
// TARGET_PROFILES already guarantees) and the effective provider
|
|
83
|
-
//
|
|
84
|
-
//
|
|
86
|
+
// TARGET_PROFILES already guarantees) and the effective provider is
|
|
87
|
+
// Anthropic. Effective provider is the explicit `provider`, else the
|
|
88
|
+
// provider implied by a known Claude `model`, else the inherited
|
|
89
|
+
// llm.default.provider. Explicit `source: "user"` profiles are always
|
|
90
|
+
// skipped.
|
|
85
91
|
if (profile.source === "user") continue;
|
|
86
92
|
if (profile.source !== undefined && profile.source !== "managed") {
|
|
87
93
|
continue;
|
|
88
94
|
}
|
|
89
|
-
const effectiveProvider =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
const effectiveProvider = resolveEffectiveProvider(
|
|
96
|
+
profile,
|
|
97
|
+
defaultProvider,
|
|
98
|
+
);
|
|
93
99
|
if (effectiveProvider !== "anthropic") continue;
|
|
94
100
|
|
|
95
101
|
// Skip if thinking is already enabled.
|
|
@@ -112,6 +118,27 @@ export const enableAdaptiveThinkingManagedProfilesMigration: WorkspaceMigration
|
|
|
112
118
|
},
|
|
113
119
|
};
|
|
114
120
|
|
|
121
|
+
// Inline, conservative mirror of the resolver's catalog-based provider
|
|
122
|
+
// implication. Migration modules are frozen, self-contained snapshots and must
|
|
123
|
+
// not import the live model catalog. Anthropic's catalog model ids are bare
|
|
124
|
+
// `claude-*` ids (the slash-prefixed `anthropic/claude-*` ids belong to
|
|
125
|
+
// OpenRouter), so a profile pinning a `claude-*` model with no slash counts as
|
|
126
|
+
// Anthropic.
|
|
127
|
+
function resolveEffectiveProvider(
|
|
128
|
+
profile: Record<string, unknown>,
|
|
129
|
+
defaultProvider: string,
|
|
130
|
+
): string {
|
|
131
|
+
if (typeof profile.provider === "string") return profile.provider;
|
|
132
|
+
if (
|
|
133
|
+
typeof profile.model === "string" &&
|
|
134
|
+
profile.model.startsWith("claude-") &&
|
|
135
|
+
!profile.model.includes("/")
|
|
136
|
+
) {
|
|
137
|
+
return "anthropic";
|
|
138
|
+
}
|
|
139
|
+
return defaultProvider;
|
|
140
|
+
}
|
|
141
|
+
|
|
115
142
|
function readObject(value: unknown): Record<string, unknown> | null {
|
|
116
143
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
117
144
|
return null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { MigrationRunContext, WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Preserve heartbeat behavior for existing workspaces after the schema
|
|
8
|
+
* default for `heartbeat.enabled` flipped from true to false (heartbeats are
|
|
9
|
+
* now opt-in for new users).
|
|
10
|
+
*
|
|
11
|
+
* Most configs never persist `heartbeat.enabled` — they relied on the old
|
|
12
|
+
* default-on schema behavior, so flipping the default would silently turn
|
|
13
|
+
* heartbeats off on upgrade. This migration writes an explicit
|
|
14
|
+
* `enabled: true` for upgrading workspaces that have no persisted value,
|
|
15
|
+
* keeping their effective behavior unchanged. Workspaces with an explicit
|
|
16
|
+
* `enabled` value (either way) are a user choice and are left untouched.
|
|
17
|
+
* Fresh workspaces are skipped so new users start with heartbeats off.
|
|
18
|
+
*/
|
|
19
|
+
export const preserveHeartbeatEnabledForExistingWorkspacesMigration: WorkspaceMigration =
|
|
20
|
+
{
|
|
21
|
+
id: "102-preserve-heartbeat-enabled-for-existing-workspaces",
|
|
22
|
+
description:
|
|
23
|
+
"Persist heartbeat.enabled=true for existing workspaces now that the default is off",
|
|
24
|
+
run(workspaceDir: string, ctx?: MigrationRunContext): void {
|
|
25
|
+
// Fresh workspaces get the new opt-in default. Without a context
|
|
26
|
+
// (older callers), treat the workspace as existing — writing
|
|
27
|
+
// enabled=true reproduces the legacy default and never disables
|
|
28
|
+
// heartbeats for anyone.
|
|
29
|
+
if (ctx?.isNewWorkspace) return;
|
|
30
|
+
|
|
31
|
+
const configPath = join(workspaceDir, "config.json");
|
|
32
|
+
|
|
33
|
+
// Existing workspaces may have no config.json at all (schema defaults
|
|
34
|
+
// are applied in memory at load time); create one so the legacy
|
|
35
|
+
// default-on behavior survives the flip.
|
|
36
|
+
let config: Record<string, unknown> = {};
|
|
37
|
+
if (existsSync(configPath)) {
|
|
38
|
+
try {
|
|
39
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
40
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
41
|
+
config = raw as Record<string, unknown>;
|
|
42
|
+
} catch {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (config.heartbeat === undefined) {
|
|
48
|
+
config.heartbeat = {};
|
|
49
|
+
}
|
|
50
|
+
const heartbeat = config.heartbeat;
|
|
51
|
+
if (
|
|
52
|
+
!heartbeat ||
|
|
53
|
+
typeof heartbeat !== "object" ||
|
|
54
|
+
Array.isArray(heartbeat)
|
|
55
|
+
) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const heartbeatConfig = heartbeat as Record<string, unknown>;
|
|
60
|
+
if ("enabled" in heartbeatConfig) return;
|
|
61
|
+
|
|
62
|
+
heartbeatConfig.enabled = true;
|
|
63
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
64
|
+
},
|
|
65
|
+
down(_workspaceDir: string): void {
|
|
66
|
+
// Forward-only: cannot distinguish users who explicitly enabled
|
|
67
|
+
// heartbeats from those opted in by this migration.
|
|
68
|
+
},
|
|
69
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Move the managed quality-optimized profile from Claude Fable 5 to Opus 4.8.
|
|
7
|
+
//
|
|
8
|
+
// The quality-optimized intent maps to claude-opus-4-8, but the intent map is
|
|
9
|
+
// only consulted when a profile is seeded: off-platform installs reseed
|
|
10
|
+
// managed profiles on every boot, while on-platform workspaces keep the
|
|
11
|
+
// profile they were hatched with — the seeder skips existing profiles there,
|
|
12
|
+
// and the hatch overlay is consumed exactly once. A platform workspace holding
|
|
13
|
+
// a Claude Fable 5 quality-optimized profile therefore keeps it until a
|
|
14
|
+
// migration rewrites it.
|
|
15
|
+
//
|
|
16
|
+
// Only the managed quality-optimized profile is touched — the user-owned
|
|
17
|
+
// custom-quality-optimized copy is theirs to manage. Within it, only a profile
|
|
18
|
+
// still on claude-fable-5 is rewritten — matching by model value also covers
|
|
19
|
+
// the OpenRouter-prefixed id. A profile whose model the user changed to
|
|
20
|
+
// anything else is left untouched.
|
|
21
|
+
|
|
22
|
+
const TARGET_PROFILES = ["quality-optimized"];
|
|
23
|
+
|
|
24
|
+
const MODEL_UPGRADES: Record<string, string> = {
|
|
25
|
+
"claude-fable-5": "claude-opus-4-8",
|
|
26
|
+
"anthropic/claude-fable-5": "anthropic/claude-opus-4.8",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const upgradeQualityProfileToOpus48Migration: WorkspaceMigration = {
|
|
30
|
+
id: "103-upgrade-quality-profile-to-opus-4-8",
|
|
31
|
+
description:
|
|
32
|
+
"Move the managed quality-optimized profile from Claude Fable 5 to Opus 4.8",
|
|
33
|
+
run(workspaceDir: string): void {
|
|
34
|
+
const configPath = join(workspaceDir, "config.json");
|
|
35
|
+
if (!existsSync(configPath)) return;
|
|
36
|
+
|
|
37
|
+
let config: Record<string, unknown>;
|
|
38
|
+
try {
|
|
39
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
40
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
41
|
+
config = raw as Record<string, unknown>;
|
|
42
|
+
} catch {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const llm = readObject(config.llm);
|
|
47
|
+
if (llm === null) return;
|
|
48
|
+
|
|
49
|
+
const profiles = readObject(llm.profiles);
|
|
50
|
+
if (profiles === null) return;
|
|
51
|
+
|
|
52
|
+
let changed = false;
|
|
53
|
+
|
|
54
|
+
for (const name of TARGET_PROFILES) {
|
|
55
|
+
const profile = readObject(profiles[name]);
|
|
56
|
+
if (profile === null) continue;
|
|
57
|
+
if (typeof profile.model !== "string") continue;
|
|
58
|
+
|
|
59
|
+
const upgraded = MODEL_UPGRADES[profile.model];
|
|
60
|
+
if (upgraded === undefined) continue;
|
|
61
|
+
|
|
62
|
+
profile.model = upgraded;
|
|
63
|
+
profiles[name] = profile;
|
|
64
|
+
changed = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (changed) {
|
|
68
|
+
llm.profiles = profiles;
|
|
69
|
+
config.llm = llm;
|
|
70
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
down(_workspaceDir: string): void {
|
|
74
|
+
// Forward-only.
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
79
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return value as Record<string, unknown>;
|
|
83
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Re-run the adaptive-thinking repair on managed "balanced" and
|
|
7
|
+
// "quality-optimized" profiles, this time honoring the provider implied by a
|
|
8
|
+
// known Claude `model`.
|
|
9
|
+
//
|
|
10
|
+
// Migration 097 patches managed Anthropic profiles to enable adaptive thinking.
|
|
11
|
+
// Its original release classified a source-less profile by
|
|
12
|
+
// `profile.provider ?? llm.default.provider`, so a profile that omits
|
|
13
|
+
// `provider` but pins a known Claude `model` under a non-Anthropic default was
|
|
14
|
+
// treated as non-Anthropic and skipped — even though the resolver implies
|
|
15
|
+
// Anthropic from the model id. 097's frozen copy was later corrected to imply
|
|
16
|
+
// the provider from the model, but workspaces that already ran 097 have it
|
|
17
|
+
// checkpointed as completed, so the corrected logic never re-runs for them.
|
|
18
|
+
// The live startup repair (adaptive-thinking-repair.ts) only runs behind the
|
|
19
|
+
// hatch overlay, which is archived after hatch, so already-hatched platform
|
|
20
|
+
// instances are not covered either.
|
|
21
|
+
//
|
|
22
|
+
// This migration re-applies the corrected repair once for those checkpointed
|
|
23
|
+
// workspaces. It is idempotent: profiles that already have thinking enabled are
|
|
24
|
+
// left untouched, so workspaces that were already patched (or that never had
|
|
25
|
+
// the gap) are no-ops.
|
|
26
|
+
//
|
|
27
|
+
// The migration keeps its own frozen copy of the logic because migration
|
|
28
|
+
// modules are self-contained snapshots and must never be imported by other
|
|
29
|
+
// code.
|
|
30
|
+
|
|
31
|
+
const ADAPTIVE_THINKING = { enabled: true, streamThinking: true } as const;
|
|
32
|
+
const TARGET_PROFILES = ["balanced", "quality-optimized"] as const;
|
|
33
|
+
|
|
34
|
+
export const recheckAdaptiveThinkingModelImpliedAnthropicMigration: WorkspaceMigration =
|
|
35
|
+
{
|
|
36
|
+
id: "104-recheck-adaptive-thinking-model-implied-anthropic",
|
|
37
|
+
description:
|
|
38
|
+
"Re-enable adaptive thinking on managed profiles that imply Anthropic via a known Claude model",
|
|
39
|
+
run(workspaceDir: string): void {
|
|
40
|
+
const configPath = join(workspaceDir, "config.json");
|
|
41
|
+
if (!existsSync(configPath)) return;
|
|
42
|
+
|
|
43
|
+
let config: Record<string, unknown>;
|
|
44
|
+
try {
|
|
45
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
46
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
47
|
+
config = raw as Record<string, unknown>;
|
|
48
|
+
} catch {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const llm = readObject(config.llm);
|
|
53
|
+
if (llm === null) return;
|
|
54
|
+
|
|
55
|
+
const profiles = readObject(llm.profiles);
|
|
56
|
+
if (profiles === null) return;
|
|
57
|
+
|
|
58
|
+
// Profiles without an explicit provider and without a model-implied
|
|
59
|
+
// provider inherit llm.default.provider at resolution time; an absent
|
|
60
|
+
// llm.default.provider resolves to Anthropic.
|
|
61
|
+
const defaultBlock = readObject(llm.default);
|
|
62
|
+
const defaultProvider =
|
|
63
|
+
typeof defaultBlock?.provider === "string"
|
|
64
|
+
? defaultBlock.provider
|
|
65
|
+
: "anthropic";
|
|
66
|
+
|
|
67
|
+
let changed = false;
|
|
68
|
+
|
|
69
|
+
for (const name of TARGET_PROFILES) {
|
|
70
|
+
const profile = readObject(profiles[name]);
|
|
71
|
+
if (profile === null) continue;
|
|
72
|
+
|
|
73
|
+
// Only patch managed Anthropic profiles. Explicit `source: "user"`
|
|
74
|
+
// profiles and non-managed, non-absent sources are skipped. Effective
|
|
75
|
+
// provider is the explicit `provider`, else the provider implied by a
|
|
76
|
+
// known Claude `model`, else the inherited llm.default.provider.
|
|
77
|
+
if (profile.source === "user") continue;
|
|
78
|
+
if (profile.source !== undefined && profile.source !== "managed") {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const effectiveProvider = resolveEffectiveProvider(
|
|
82
|
+
profile,
|
|
83
|
+
defaultProvider,
|
|
84
|
+
);
|
|
85
|
+
if (effectiveProvider !== "anthropic") continue;
|
|
86
|
+
|
|
87
|
+
// Skip if thinking is already enabled.
|
|
88
|
+
const thinking = readObject(profile.thinking);
|
|
89
|
+
if (thinking !== null && thinking.enabled === true) continue;
|
|
90
|
+
|
|
91
|
+
profile.thinking = { ...ADAPTIVE_THINKING };
|
|
92
|
+
profiles[name] = profile;
|
|
93
|
+
changed = true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (changed) {
|
|
97
|
+
llm.profiles = profiles;
|
|
98
|
+
config.llm = llm;
|
|
99
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
down(_workspaceDir: string): void {
|
|
103
|
+
// Forward-only.
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Inline, conservative mirror of the resolver's catalog-based provider
|
|
108
|
+
// implication. Migration modules are frozen, self-contained snapshots and must
|
|
109
|
+
// not import the live model catalog. Anthropic's catalog model ids are bare
|
|
110
|
+
// `claude-*` ids (the slash-prefixed `anthropic/claude-*` ids belong to
|
|
111
|
+
// OpenRouter), so a profile pinning a `claude-*` model with no slash counts as
|
|
112
|
+
// Anthropic.
|
|
113
|
+
function resolveEffectiveProvider(
|
|
114
|
+
profile: Record<string, unknown>,
|
|
115
|
+
defaultProvider: string,
|
|
116
|
+
): string {
|
|
117
|
+
if (typeof profile.provider === "string") return profile.provider;
|
|
118
|
+
if (
|
|
119
|
+
typeof profile.model === "string" &&
|
|
120
|
+
profile.model.startsWith("claude-") &&
|
|
121
|
+
!profile.model.includes("/")
|
|
122
|
+
) {
|
|
123
|
+
return "anthropic";
|
|
124
|
+
}
|
|
125
|
+
return defaultProvider;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
129
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return value as Record<string, unknown>;
|
|
133
|
+
}
|
|
@@ -99,6 +99,9 @@ import { removeStaleUpdatesBulletinFileMigration } from "./098-remove-stale-upda
|
|
|
99
99
|
import { disableCacheOneShotCallsitesMigration } from "./099-disable-cache-one-shot-callsites.js";
|
|
100
100
|
import { upgradeQualityProfileToFable5Migration } from "./100-upgrade-quality-profile-to-fable-5.js";
|
|
101
101
|
import { upgradeBalancedEconomyToMinimaxM3Migration } from "./101-upgrade-balanced-economy-to-minimax-m3.js";
|
|
102
|
+
import { preserveHeartbeatEnabledForExistingWorkspacesMigration } from "./102-preserve-heartbeat-enabled-for-existing-workspaces.js";
|
|
103
|
+
import { upgradeQualityProfileToOpus48Migration } from "./103-upgrade-quality-profile-to-opus-4-8.js";
|
|
104
|
+
import { recheckAdaptiveThinkingModelImpliedAnthropicMigration } from "./104-recheck-adaptive-thinking-model-implied-anthropic.js";
|
|
102
105
|
import { migrateToWorkspaceVolumeMigration } from "./migrate-to-workspace-volume.js";
|
|
103
106
|
import type { WorkspaceMigration } from "./types.js";
|
|
104
107
|
|
|
@@ -209,4 +212,7 @@ export const WORKSPACE_MIGRATIONS: WorkspaceMigration[] = [
|
|
|
209
212
|
disableCacheOneShotCallsitesMigration,
|
|
210
213
|
upgradeQualityProfileToFable5Migration,
|
|
211
214
|
upgradeBalancedEconomyToMinimaxM3Migration,
|
|
215
|
+
preserveHeartbeatEnabledForExistingWorkspacesMigration,
|
|
216
|
+
upgradeQualityProfileToOpus48Migration,
|
|
217
|
+
recheckAdaptiveThinkingModelImpliedAnthropicMigration,
|
|
212
218
|
];
|
|
@@ -197,7 +197,7 @@ export async function runWorkspaceMigrations(
|
|
|
197
197
|
* workspace migrations while the assistant is running may cause file conflicts,
|
|
198
198
|
* stale caches, or data corruption.
|
|
199
199
|
*
|
|
200
|
-
* @param workspaceDir The workspace directory path (e.g.,
|
|
200
|
+
* @param workspaceDir The workspace directory path (e.g., `$VELLUM_WORKSPACE_DIR`).
|
|
201
201
|
* @param migrations The full ordered array of workspace migrations (from `WORKSPACE_MIGRATIONS`).
|
|
202
202
|
* @param targetMigrationId The migration ID to roll back to (exclusive — all
|
|
203
203
|
* migrations after this one are reversed).
|
package/tsconfig.json
CHANGED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
GuardianActionMessageContext,
|
|
5
|
-
GuardianActionMessageScenario,
|
|
6
|
-
} from "../runtime/guardian-action-message-composer.js";
|
|
7
|
-
import {
|
|
8
|
-
composeGuardianActionMessageGenerative,
|
|
9
|
-
getGuardianActionFallbackMessage,
|
|
10
|
-
} from "../runtime/guardian-action-message-composer.js";
|
|
11
|
-
import type { GuardianActionCopyGenerator } from "../runtime/http-types.js";
|
|
12
|
-
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// Every scenario must produce a non-empty string
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
const ALL_SCENARIOS: GuardianActionMessageScenario[] = [
|
|
18
|
-
"caller_timeout_acknowledgment",
|
|
19
|
-
"caller_timeout_continue",
|
|
20
|
-
"guardian_late_answer_followup",
|
|
21
|
-
"guardian_followup_dispatching",
|
|
22
|
-
"guardian_followup_completed",
|
|
23
|
-
"guardian_followup_failed",
|
|
24
|
-
"guardian_followup_declined_ack",
|
|
25
|
-
"guardian_followup_clarification",
|
|
26
|
-
"guardian_pending_disambiguation",
|
|
27
|
-
"guardian_expired_disambiguation",
|
|
28
|
-
"guardian_followup_disambiguation",
|
|
29
|
-
"guardian_stale_answered",
|
|
30
|
-
"guardian_stale_expired",
|
|
31
|
-
"guardian_stale_followup",
|
|
32
|
-
"guardian_stale_superseded",
|
|
33
|
-
"guardian_superseded_remap",
|
|
34
|
-
"guardian_unknown_code",
|
|
35
|
-
"guardian_auto_matched",
|
|
36
|
-
"followup_call_started",
|
|
37
|
-
"followup_action_failed",
|
|
38
|
-
"guardian_answer_delivery_failed",
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
describe("guardian-action-copy-generator", () => {
|
|
42
|
-
// -----------------------------------------------------------------------
|
|
43
|
-
// Fallback messages -- every scenario produces non-empty output
|
|
44
|
-
// -----------------------------------------------------------------------
|
|
45
|
-
|
|
46
|
-
describe("getGuardianActionFallbackMessage", () => {
|
|
47
|
-
for (const scenario of ALL_SCENARIOS) {
|
|
48
|
-
test(`scenario "${scenario}" produces a non-empty string`, () => {
|
|
49
|
-
const msg = getGuardianActionFallbackMessage({ scenario });
|
|
50
|
-
expect(typeof msg).toBe("string");
|
|
51
|
-
expect(msg.trim().length).toBeGreaterThan(0);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
test("caller_timeout_acknowledgment includes guardianIdentifier when provided", () => {
|
|
56
|
-
const msg = getGuardianActionFallbackMessage({
|
|
57
|
-
scenario: "caller_timeout_acknowledgment",
|
|
58
|
-
guardianIdentifier: "Dr. Smith",
|
|
59
|
-
});
|
|
60
|
-
expect(msg).toContain("Dr. Smith");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("guardian_late_answer_followup includes callerIdentifier when provided", () => {
|
|
64
|
-
const msg = getGuardianActionFallbackMessage({
|
|
65
|
-
scenario: "guardian_late_answer_followup",
|
|
66
|
-
callerIdentifier: "Alice",
|
|
67
|
-
});
|
|
68
|
-
expect(msg).toContain("Alice");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test("guardian_followup_dispatching includes followupAction when provided", () => {
|
|
72
|
-
const msg = getGuardianActionFallbackMessage({
|
|
73
|
-
scenario: "guardian_followup_dispatching",
|
|
74
|
-
followupAction: "send them a text message",
|
|
75
|
-
});
|
|
76
|
-
expect(msg).toContain("send them a text message");
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("guardian_followup_completed includes followupAction when provided", () => {
|
|
80
|
-
const msg = getGuardianActionFallbackMessage({
|
|
81
|
-
scenario: "guardian_followup_completed",
|
|
82
|
-
followupAction: "sent the message",
|
|
83
|
-
});
|
|
84
|
-
expect(msg).toContain("sent the message");
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test("guardian_followup_failed includes failureReason when provided", () => {
|
|
88
|
-
const msg = getGuardianActionFallbackMessage({
|
|
89
|
-
scenario: "guardian_followup_failed",
|
|
90
|
-
failureReason: "The phone number is not valid.",
|
|
91
|
-
});
|
|
92
|
-
expect(msg).toContain("The phone number is not valid.");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test("guardian_expired_disambiguation includes request codes when provided", () => {
|
|
96
|
-
const msg = getGuardianActionFallbackMessage({
|
|
97
|
-
scenario: "guardian_expired_disambiguation",
|
|
98
|
-
requestCodes: ["Q1A2B3", "Q9Z8Y7"],
|
|
99
|
-
});
|
|
100
|
-
expect(msg).toContain("Q1A2B3");
|
|
101
|
-
expect(msg).toContain("Q9Z8Y7");
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test("guardian_followup_disambiguation includes request codes when provided", () => {
|
|
105
|
-
const msg = getGuardianActionFallbackMessage({
|
|
106
|
-
scenario: "guardian_followup_disambiguation",
|
|
107
|
-
requestCodes: ["QFOO12"],
|
|
108
|
-
});
|
|
109
|
-
expect(msg).toContain("QFOO12");
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// -----------------------------------------------------------------------
|
|
114
|
-
// composeGuardianActionMessageGenerative -- layered composition
|
|
115
|
-
// -----------------------------------------------------------------------
|
|
116
|
-
|
|
117
|
-
describe("composeGuardianActionMessageGenerative", () => {
|
|
118
|
-
test("with no generator returns fallback", async () => {
|
|
119
|
-
const context: GuardianActionMessageContext = {
|
|
120
|
-
scenario: "caller_timeout_acknowledgment",
|
|
121
|
-
guardianIdentifier: "Jane",
|
|
122
|
-
};
|
|
123
|
-
const msg = await composeGuardianActionMessageGenerative(context);
|
|
124
|
-
expect(msg).toBe(getGuardianActionFallbackMessage(context));
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test("with generator that returns text uses the generated text", async () => {
|
|
128
|
-
const generatedText = "Custom generated message about the timeout.";
|
|
129
|
-
const generator: GuardianActionCopyGenerator = async () => generatedText;
|
|
130
|
-
const context: GuardianActionMessageContext = {
|
|
131
|
-
scenario: "caller_timeout_acknowledgment",
|
|
132
|
-
};
|
|
133
|
-
// In test env, generator is skipped and fallback is returned
|
|
134
|
-
const msg = await composeGuardianActionMessageGenerative(
|
|
135
|
-
context,
|
|
136
|
-
{},
|
|
137
|
-
generator,
|
|
138
|
-
);
|
|
139
|
-
expect(msg).toBe(getGuardianActionFallbackMessage(context));
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
test("with generator that throws returns fallback", async () => {
|
|
143
|
-
const generator: GuardianActionCopyGenerator = async () => {
|
|
144
|
-
throw new Error("Provider unavailable");
|
|
145
|
-
};
|
|
146
|
-
const context: GuardianActionMessageContext = {
|
|
147
|
-
scenario: "guardian_followup_failed",
|
|
148
|
-
failureReason: "Network error",
|
|
149
|
-
};
|
|
150
|
-
const msg = await composeGuardianActionMessageGenerative(
|
|
151
|
-
context,
|
|
152
|
-
{},
|
|
153
|
-
generator,
|
|
154
|
-
);
|
|
155
|
-
expect(msg).toBe(getGuardianActionFallbackMessage(context));
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test("with generator that returns null returns fallback", async () => {
|
|
159
|
-
const generator: GuardianActionCopyGenerator = async () => null;
|
|
160
|
-
const context: GuardianActionMessageContext = {
|
|
161
|
-
scenario: "guardian_stale_expired",
|
|
162
|
-
};
|
|
163
|
-
const msg = await composeGuardianActionMessageGenerative(
|
|
164
|
-
context,
|
|
165
|
-
{},
|
|
166
|
-
generator,
|
|
167
|
-
);
|
|
168
|
-
expect(msg).toBe(getGuardianActionFallbackMessage(context));
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test("uses custom fallbackText from options when provided", async () => {
|
|
172
|
-
const context: GuardianActionMessageContext = {
|
|
173
|
-
scenario: "caller_timeout_continue",
|
|
174
|
-
};
|
|
175
|
-
const customFallback = "Custom fallback text for this scenario.";
|
|
176
|
-
const msg = await composeGuardianActionMessageGenerative(context, {
|
|
177
|
-
fallbackText: customFallback,
|
|
178
|
-
});
|
|
179
|
-
expect(msg).toBe(customFallback);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
test("skips generation in test environment", async () => {
|
|
183
|
-
let generatorCalled = false;
|
|
184
|
-
const generator: GuardianActionCopyGenerator = async () => {
|
|
185
|
-
generatorCalled = true;
|
|
186
|
-
return "This should not be returned in test env";
|
|
187
|
-
};
|
|
188
|
-
const context: GuardianActionMessageContext = {
|
|
189
|
-
scenario: "guardian_followup_declined_ack",
|
|
190
|
-
};
|
|
191
|
-
const msg = await composeGuardianActionMessageGenerative(
|
|
192
|
-
context,
|
|
193
|
-
{},
|
|
194
|
-
generator,
|
|
195
|
-
);
|
|
196
|
-
expect(generatorCalled).toBe(false);
|
|
197
|
-
expect(msg).toBe(getGuardianActionFallbackMessage(context));
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
});
|