@vellumai/assistant 0.9.0 → 0.10.0-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +18 -34
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +976 -63
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +51 -1
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +49 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +197 -4
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +105 -17
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +27 -14
- package/src/daemon/conversation.ts +66 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +202 -3
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +33 -0
- package/src/tools/subagent/spawn.ts +61 -12
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -27,7 +27,10 @@ type ManagedProfileTemplate = Omit<
|
|
|
27
27
|
ProfileEntry,
|
|
28
28
|
"provider" | "model" | "provider_connection"
|
|
29
29
|
> & {
|
|
30
|
-
intent
|
|
30
|
+
// Exactly one of `intent` or `model` must be set. `intent` resolves the
|
|
31
|
+
// model from the catalog at seed time; `model` pins an explicit model id.
|
|
32
|
+
intent?: ModelIntent;
|
|
33
|
+
model?: string;
|
|
31
34
|
provider: NonNullable<ProfileEntry["provider"]>;
|
|
32
35
|
connectionName: string;
|
|
33
36
|
};
|
|
@@ -38,17 +41,20 @@ type ManagedProfileTemplate = Omit<
|
|
|
38
41
|
* (`preserveProfileNames`) take precedence when present.
|
|
39
42
|
*/
|
|
40
43
|
const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
44
|
+
// Served by MiniMax M3 on Fireworks via managed platform inference: a strong
|
|
45
|
+
// open model at a lower price point than the managed Anthropic route.
|
|
41
46
|
balanced: {
|
|
42
47
|
intent: "balanced",
|
|
43
|
-
provider: "
|
|
44
|
-
connectionName: "
|
|
48
|
+
provider: "fireworks",
|
|
49
|
+
connectionName: "fireworks-managed",
|
|
45
50
|
source: "managed",
|
|
46
51
|
label: "Balanced",
|
|
47
52
|
description: "Good balance of quality, cost, and speed",
|
|
48
|
-
maxTokens:
|
|
53
|
+
maxTokens: 32000,
|
|
49
54
|
effort: "high",
|
|
50
55
|
thinking: { enabled: true, streamThinking: true },
|
|
51
56
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
57
|
+
topP: 0.95,
|
|
52
58
|
},
|
|
53
59
|
"quality-optimized": {
|
|
54
60
|
intent: "quality-optimized",
|
|
@@ -61,6 +67,9 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
61
67
|
effort: "high",
|
|
62
68
|
thinking: { enabled: true, streamThinking: true },
|
|
63
69
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
70
|
+
// This is the advisor's own (strongest) profile: when it's also the chat
|
|
71
|
+
// profile there's nothing stronger to consult, so the advisor defaults off.
|
|
72
|
+
advisorEnabled: false,
|
|
64
73
|
},
|
|
65
74
|
"cost-optimized": {
|
|
66
75
|
intent: "latency-optimized",
|
|
@@ -74,20 +83,6 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
74
83
|
thinking: { enabled: false, streamThinking: false },
|
|
75
84
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
76
85
|
},
|
|
77
|
-
// Open-weight economy option: MiniMax M3 served by Fireworks via managed
|
|
78
|
-
// platform inference.
|
|
79
|
-
"balanced-economy": {
|
|
80
|
-
intent: "balanced",
|
|
81
|
-
provider: "fireworks",
|
|
82
|
-
connectionName: "fireworks-managed",
|
|
83
|
-
source: "managed",
|
|
84
|
-
label: "Balanced Economy",
|
|
85
|
-
description: "Strong open model (MiniMax M3) at a lower price point",
|
|
86
|
-
maxTokens: 32000,
|
|
87
|
-
effort: "high",
|
|
88
|
-
thinking: { enabled: true, streamThinking: true },
|
|
89
|
-
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
90
|
-
},
|
|
91
86
|
};
|
|
92
87
|
|
|
93
88
|
/**
|
|
@@ -144,8 +139,37 @@ const USER_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
144
139
|
*/
|
|
145
140
|
export const AUTO_PROFILE_KEY = "auto";
|
|
146
141
|
|
|
142
|
+
export const OS_BETA_PROFILE_KEY = "os-beta";
|
|
143
|
+
export const OS_BETA_FEATURE_FLAG_KEY = "os-beta";
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Flag-gated managed profile. NOT in MANAGED_PROFILE_TEMPLATES, so the
|
|
147
|
+
* unconditional boot seed never creates it. Reconciled in/out by
|
|
148
|
+
* the flag-gated profile reconcile based on the `os-beta` feature flag.
|
|
149
|
+
* Balanced-parity defaults; GLM 5.2 pinned explicitly via `model`.
|
|
150
|
+
*/
|
|
151
|
+
export const OS_BETA_PROFILE_TEMPLATE: ManagedProfileTemplate = {
|
|
152
|
+
model: "accounts/fireworks/models/glm-5p2",
|
|
153
|
+
provider: "fireworks",
|
|
154
|
+
connectionName: "fireworks-managed",
|
|
155
|
+
source: "managed",
|
|
156
|
+
label: "OS Beta",
|
|
157
|
+
description: "Open-source frontier model (GLM 5.2), in beta",
|
|
158
|
+
maxTokens: 32000,
|
|
159
|
+
effort: "high",
|
|
160
|
+
thinking: { enabled: true, streamThinking: true },
|
|
161
|
+
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Membership here marks a name as managed. The route layer applies managed
|
|
165
|
+
// restrictions (blocking model/provider edits and deletion) only to entries
|
|
166
|
+
// whose on-disk `source` is `managed`, so a user-owned profile sharing one of
|
|
167
|
+
// these names is not locked. `OS_BETA_PROFILE_KEY` is flag-gated: it is
|
|
168
|
+
// materialized by the flag-gated profile reconcile, which refuses to touch a
|
|
169
|
+
// same-named user profile.
|
|
147
170
|
export const MANAGED_PROFILE_NAMES = new Set([
|
|
148
171
|
...Object.keys(MANAGED_PROFILE_TEMPLATES),
|
|
172
|
+
OS_BETA_PROFILE_KEY,
|
|
149
173
|
AUTO_PROFILE_KEY,
|
|
150
174
|
]);
|
|
151
175
|
|
|
@@ -167,10 +191,17 @@ export type SeedInferenceProfilesOptions = {
|
|
|
167
191
|
*
|
|
168
192
|
* Runs on every daemon startup. Two responsibilities:
|
|
169
193
|
*
|
|
170
|
-
* 1. **Managed profiles** (`balanced`, `quality-optimized`,
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
194
|
+
* 1. **Managed profiles** (`balanced`, `quality-optimized`,
|
|
195
|
+
* `cost-optimized`): reconciled from the code templates on every boot —
|
|
196
|
+
* on-platform and off-platform alike — so Vellum can push model/config
|
|
197
|
+
* updates to customers in a release without a workspace migration. The
|
|
198
|
+
* templates own all profile content; `label`, `status`, `advisorEnabled`,
|
|
199
|
+
* and `topP` are user overrides that survive reseeds. Of those, only
|
|
200
|
+
* `label`, `status`, and `topP` are editable through the managed PUT route
|
|
201
|
+
* allowlist; `advisorEnabled` is edited via the generic config path but is
|
|
202
|
+
* still preserved here so it survives reboots.
|
|
203
|
+
* Platform overlays (`preserveProfileNames`) take precedence for the boot
|
|
204
|
+
* they are supplied.
|
|
174
205
|
*
|
|
175
206
|
* 2. **User profiles** (`custom-balanced`, `custom-quality-optimized`,
|
|
176
207
|
* `custom-cost-optimized`): materialized once at hatch time for
|
|
@@ -208,24 +239,31 @@ export function seedInferenceProfiles(
|
|
|
208
239
|
// subsequent boot.
|
|
209
240
|
const isByokMode = !isPlatform;
|
|
210
241
|
|
|
211
|
-
// 1. Managed profiles.
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
242
|
+
// 1. Managed profiles. Reconciled from the code templates on every boot —
|
|
243
|
+
// on-platform and off-platform alike — so Vellum can push model/config
|
|
244
|
+
// updates in new releases just by editing `MANAGED_PROFILE_TEMPLATES` /
|
|
245
|
+
// `model-intents.ts` and shipping a release, with no workspace migration.
|
|
246
|
+
// The templates are the single source of truth for profile *content*
|
|
247
|
+
// (model, maxTokens, effort, thinking, description, provider/connection).
|
|
248
|
+
//
|
|
249
|
+
// Platform overlays (`preserveProfileNames`) still take precedence for the
|
|
250
|
+
// boot they are supplied: a profile named in the overlay is skipped here so
|
|
251
|
+
// the overlay fragment lands verbatim and is never polluted by template
|
|
252
|
+
// fields it omits. The overlay is a one-time hatch input (archived after
|
|
253
|
+
// its first merge), so on subsequent boots the templates reconcile content
|
|
254
|
+
// as usual.
|
|
221
255
|
//
|
|
222
|
-
//
|
|
223
|
-
// rename)
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
256
|
+
// A whitelist of user-editable fields survives the reconcile: `label`
|
|
257
|
+
// (display rename), `status` (active/disabled toggle), `advisorEnabled`
|
|
258
|
+
// (per-profile advisor toggle), and `topP` (sampling override) — the only
|
|
259
|
+
// fields a user may override. The managed PUT route
|
|
260
|
+
// `/v1/config/llm/profiles/:name` lets users patch `label`, `status`, and
|
|
261
|
+
// `topP` on managed profiles without duplicating (its editable allowlist,
|
|
262
|
+
// `MANAGED_PROFILE_EDITABLE_KEYS`, deliberately excludes `advisorEnabled`,
|
|
263
|
+
// which is set through the generic config path). We honor every one of
|
|
264
|
+
// these overrides across reseeds or they'd silently revert on every boot.
|
|
265
|
+
// Carry by key-presence rather than truthiness so an explicit `null` (user
|
|
266
|
+
// cleared the field) survives too.
|
|
229
267
|
//
|
|
230
268
|
// BYOK seed defaults (off-platform only):
|
|
231
269
|
// • label: " (Managed)" suffix disambiguates managed profile labels
|
|
@@ -249,7 +287,6 @@ export function seedInferenceProfiles(
|
|
|
249
287
|
|
|
250
288
|
for (const [name, template] of Object.entries(MANAGED_PROFILE_TEMPLATES)) {
|
|
251
289
|
if (preservedProfileNames.has(name)) continue;
|
|
252
|
-
if (isPlatform && readObject(profiles[name]) !== null) continue;
|
|
253
290
|
|
|
254
291
|
const previous = readObject(profiles[name]);
|
|
255
292
|
const effectiveTemplate: ManagedProfileTemplate = isByokMode
|
|
@@ -281,6 +318,18 @@ export function seedInferenceProfiles(
|
|
|
281
318
|
: previous.label;
|
|
282
319
|
}
|
|
283
320
|
if ("status" in previous) next.status = previous.status;
|
|
321
|
+
// The per-profile advisor toggle is a user override — preserve it across
|
|
322
|
+
// reseeds so a user's choice survives reboots (the template value only
|
|
323
|
+
// seeds the initial default, e.g. off for quality-optimized).
|
|
324
|
+
if ("advisorEnabled" in previous) {
|
|
325
|
+
next.advisorEnabled = previous.advisorEnabled;
|
|
326
|
+
}
|
|
327
|
+
// `topP` is user-editable on managed profiles (see the managed-profile
|
|
328
|
+
// editable allowlist on the PUT route) — preserve a user override across
|
|
329
|
+
// reseeds, including an explicit `null` clear, or it would silently revert
|
|
330
|
+
// to the template value on every boot. Carry by key-presence (not
|
|
331
|
+
// truthiness) so `null` survives too.
|
|
332
|
+
if ("topP" in previous) next.topP = previous.topP;
|
|
284
333
|
}
|
|
285
334
|
profiles[name] = next as ProfileEntry;
|
|
286
335
|
}
|
|
@@ -364,6 +413,17 @@ export function seedInferenceProfiles(
|
|
|
364
413
|
}
|
|
365
414
|
}
|
|
366
415
|
|
|
416
|
+
// Advisor profile: default to the strongest managed profile when unset, so
|
|
417
|
+
// the advisor consults `quality-optimized` out of the box. Guarded on
|
|
418
|
+
// existence so it never names a missing profile (superRefine rejects that);
|
|
419
|
+
// off-platform/BYOK installs can repoint it at one of their own profiles.
|
|
420
|
+
if (
|
|
421
|
+
readString(llm.advisorProfile) === undefined &&
|
|
422
|
+
readObject(profiles["quality-optimized"]) !== null
|
|
423
|
+
) {
|
|
424
|
+
llm.advisorProfile = "quality-optimized";
|
|
425
|
+
}
|
|
426
|
+
|
|
367
427
|
// Profile ordering — ensure all seeded profiles appear in the order array.
|
|
368
428
|
// "auto" is prepended so it appears first in the picker.
|
|
369
429
|
const profileOrder = Array.isArray(llm.profileOrder)
|
|
@@ -405,21 +465,26 @@ export function seedInferenceProfiles(
|
|
|
405
465
|
saveRawConfig(config);
|
|
406
466
|
}
|
|
407
467
|
|
|
408
|
-
function materializeProfile(
|
|
468
|
+
export function materializeProfile(
|
|
409
469
|
template: ManagedProfileTemplate,
|
|
410
470
|
provider: NonNullable<ProfileEntry["provider"]>,
|
|
411
471
|
connectionName: string,
|
|
412
472
|
): ProfileEntry {
|
|
413
|
-
const { intent, provider: _p, connectionName: _c, ...rest } = template;
|
|
473
|
+
const { intent, model, provider: _p, connectionName: _c, ...rest } = template;
|
|
474
|
+
const resolvedModel =
|
|
475
|
+
model ?? (intent ? resolveModelIntent(provider, intent) : undefined);
|
|
476
|
+
if (!resolvedModel) {
|
|
477
|
+
throw new Error("ManagedProfileTemplate requires `intent` or `model`");
|
|
478
|
+
}
|
|
414
479
|
return {
|
|
415
480
|
...rest,
|
|
416
481
|
provider,
|
|
417
482
|
provider_connection: connectionName,
|
|
418
|
-
model:
|
|
483
|
+
model: resolvedModel,
|
|
419
484
|
};
|
|
420
485
|
}
|
|
421
486
|
|
|
422
|
-
function readObject(value: unknown): Record<string, unknown> | null {
|
|
487
|
+
export function readObject(value: unknown): Record<string, unknown> | null {
|
|
423
488
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
424
489
|
? (value as Record<string, unknown>)
|
|
425
490
|
: null;
|
package/src/config/skills.ts
CHANGED
|
@@ -47,6 +47,7 @@ const VellumMetadataSchema = z
|
|
|
47
47
|
"activation-hints": z.array(z.string()).optional(),
|
|
48
48
|
"avoid-when": z.array(z.string()).optional(),
|
|
49
49
|
category: z.string().optional(),
|
|
50
|
+
"always-candidate": z.boolean().optional(),
|
|
50
51
|
})
|
|
51
52
|
.passthrough();
|
|
52
53
|
|
|
@@ -109,6 +110,13 @@ export interface SkillSummary {
|
|
|
109
110
|
avoidWhen?: string[];
|
|
110
111
|
/** Category slug declared in frontmatter, used as a fallback when the skill is not in the Vellum catalog. */
|
|
111
112
|
category?: string;
|
|
113
|
+
/**
|
|
114
|
+
* When true, this skill is pinned into the memory-v3 selector's stable-prefix
|
|
115
|
+
* candidate pool every turn (so the selector can choose it even when no
|
|
116
|
+
* retrieval lane surfaces it). For cross-cutting capabilities whose relevance
|
|
117
|
+
* the model must judge, not embedding similarity.
|
|
118
|
+
*/
|
|
119
|
+
alwaysCandidate?: boolean;
|
|
112
120
|
/** Parsed inline command expansion descriptors (`!\`command\``) found in the skill body. */
|
|
113
121
|
inlineCommandExpansions?: InlineCommandExpansion[];
|
|
114
122
|
}
|
|
@@ -227,6 +235,7 @@ interface ParsedFrontmatter {
|
|
|
227
235
|
activationHints?: string[];
|
|
228
236
|
avoidWhen?: string[];
|
|
229
237
|
category?: string;
|
|
238
|
+
alwaysCandidate?: boolean;
|
|
230
239
|
inlineCommandExpansions?: InlineCommandExpansion[];
|
|
231
240
|
}
|
|
232
241
|
|
|
@@ -342,6 +351,11 @@ function parseFrontmatter(
|
|
|
342
351
|
? vellum.category.trim()
|
|
343
352
|
: undefined;
|
|
344
353
|
|
|
354
|
+
const alwaysCandidate =
|
|
355
|
+
typeof vellum?.["always-candidate"] === "boolean"
|
|
356
|
+
? vellum["always-candidate"]
|
|
357
|
+
: undefined;
|
|
358
|
+
|
|
345
359
|
const strippedBody = stripCommentLines(body);
|
|
346
360
|
|
|
347
361
|
// Parse inline command expansions from the body (after frontmatter/comment stripping)
|
|
@@ -366,6 +380,7 @@ function parseFrontmatter(
|
|
|
366
380
|
activationHints,
|
|
367
381
|
avoidWhen,
|
|
368
382
|
category,
|
|
383
|
+
alwaysCandidate,
|
|
369
384
|
inlineCommandExpansions,
|
|
370
385
|
};
|
|
371
386
|
}
|
|
@@ -523,6 +538,7 @@ function readSkillFromDirectory(
|
|
|
523
538
|
activationHints: parsed.activationHints,
|
|
524
539
|
avoidWhen: parsed.avoidWhen,
|
|
525
540
|
category: parsed.category,
|
|
541
|
+
alwaysCandidate: parsed.alwaysCandidate,
|
|
526
542
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
527
543
|
};
|
|
528
544
|
} catch (err) {
|
|
@@ -576,6 +592,7 @@ function readBundledSkillFromDirectory(
|
|
|
576
592
|
activationHints: parsed.activationHints,
|
|
577
593
|
avoidWhen: parsed.avoidWhen,
|
|
578
594
|
category: parsed.category,
|
|
595
|
+
alwaysCandidate: parsed.alwaysCandidate,
|
|
579
596
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
580
597
|
};
|
|
581
598
|
} catch (err) {
|
|
@@ -637,6 +654,7 @@ function loadBundledSkills(): SkillSummary[] {
|
|
|
637
654
|
activationHints: skill.activationHints,
|
|
638
655
|
avoidWhen: skill.avoidWhen,
|
|
639
656
|
category: skill.category,
|
|
657
|
+
alwaysCandidate: skill.alwaysCandidate,
|
|
640
658
|
inlineCommandExpansions: skill.inlineCommandExpansions,
|
|
641
659
|
});
|
|
642
660
|
}
|
|
@@ -764,6 +782,7 @@ function skillSummaryFromDefinition(
|
|
|
764
782
|
activationHints: skill.activationHints,
|
|
765
783
|
avoidWhen: skill.avoidWhen,
|
|
766
784
|
category: skill.category,
|
|
785
|
+
alwaysCandidate: skill.alwaysCandidate,
|
|
767
786
|
inlineCommandExpansions: skill.inlineCommandExpansions,
|
|
768
787
|
};
|
|
769
788
|
}
|
|
@@ -818,6 +837,7 @@ export function loadSkillCatalog(
|
|
|
818
837
|
activationHints: parsed.activationHints,
|
|
819
838
|
avoidWhen: parsed.avoidWhen,
|
|
820
839
|
category: parsed.category,
|
|
840
|
+
alwaysCandidate: parsed.alwaysCandidate,
|
|
821
841
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
822
842
|
});
|
|
823
843
|
} catch (err) {
|
|
@@ -954,6 +974,7 @@ export function loadSkillCatalog(
|
|
|
954
974
|
activationHints: parsed.activationHints,
|
|
955
975
|
avoidWhen: parsed.avoidWhen,
|
|
956
976
|
category: parsed.category,
|
|
977
|
+
alwaysCandidate: parsed.alwaysCandidate,
|
|
957
978
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
958
979
|
};
|
|
959
980
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
|
|
3
|
+
import { getLogger } from "../util/logger.js";
|
|
4
|
+
import { isAssistantFeatureFlagEnabled } from "./assistant-feature-flags.js";
|
|
5
|
+
import {
|
|
6
|
+
getConfigReadOnly,
|
|
7
|
+
invalidateConfigCache,
|
|
8
|
+
loadRawConfig,
|
|
9
|
+
saveRawConfig,
|
|
10
|
+
} from "./loader.js";
|
|
11
|
+
import type { ProfileEntry } from "./schemas/llm.js";
|
|
12
|
+
import {
|
|
13
|
+
materializeProfile,
|
|
14
|
+
OS_BETA_FEATURE_FLAG_KEY,
|
|
15
|
+
OS_BETA_PROFILE_KEY,
|
|
16
|
+
OS_BETA_PROFILE_TEMPLATE,
|
|
17
|
+
readObject,
|
|
18
|
+
} from "./seed-inference-profiles.js";
|
|
19
|
+
|
|
20
|
+
const log = getLogger("sync-gated-profiles");
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Reconcile flag-gated managed profiles against the current feature-flag state.
|
|
24
|
+
*
|
|
25
|
+
* `seedInferenceProfiles()` runs synchronously at boot before feature flags are
|
|
26
|
+
* available, so the OS Beta profile (GLM 5.2 / fireworks-managed) is materialized
|
|
27
|
+
* here once flags have loaded. When the `os-beta` flag is on, the managed profile
|
|
28
|
+
* is created (ordered right after `balanced`); when it is off, a previously
|
|
29
|
+
* managed entry is removed with `profileOrder` / `activeProfile` / `advisorProfile`
|
|
30
|
+
* fallbacks. The reconcile is idempotent and never touches a user-owned profile of
|
|
31
|
+
* the same name.
|
|
32
|
+
*
|
|
33
|
+
* Returns whether the on-disk config changed.
|
|
34
|
+
*/
|
|
35
|
+
export function reconcileFlagGatedProfiles(): boolean {
|
|
36
|
+
const config = loadRawConfig();
|
|
37
|
+
|
|
38
|
+
if (config.llm == null || typeof config.llm !== "object") {
|
|
39
|
+
config.llm = {};
|
|
40
|
+
}
|
|
41
|
+
const llm = config.llm as Record<string, unknown>;
|
|
42
|
+
|
|
43
|
+
if (llm.profiles == null || typeof llm.profiles !== "object") {
|
|
44
|
+
llm.profiles = {};
|
|
45
|
+
}
|
|
46
|
+
const profiles = llm.profiles as Record<string, Record<string, unknown>>;
|
|
47
|
+
|
|
48
|
+
const profileOrder = Array.isArray(llm.profileOrder)
|
|
49
|
+
? (llm.profileOrder as string[])
|
|
50
|
+
: [];
|
|
51
|
+
llm.profileOrder = profileOrder;
|
|
52
|
+
|
|
53
|
+
// The resolver reads flag state from the gateway-populated override cache and
|
|
54
|
+
// ignores the config argument; pass the read-only config for signature parity
|
|
55
|
+
// without mutating disk before the reconcile decision is made.
|
|
56
|
+
const enabled = isAssistantFeatureFlagEnabled(
|
|
57
|
+
OS_BETA_FEATURE_FLAG_KEY,
|
|
58
|
+
getConfigReadOnly(),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const isPlatform =
|
|
62
|
+
process.env.IS_PLATFORM === "true" || process.env.IS_PLATFORM === "1";
|
|
63
|
+
const isByokMode = !isPlatform;
|
|
64
|
+
|
|
65
|
+
const previous = readObject(profiles[OS_BETA_PROFILE_KEY]);
|
|
66
|
+
|
|
67
|
+
// Never clobber a user-owned profile that happens to be named `os-beta`. The
|
|
68
|
+
// entry is ours to manage only when it is absent or already managed; a
|
|
69
|
+
// user-sourced entry of the same name is left untouched on every path.
|
|
70
|
+
const isOursToManage = previous == null || previous.source === "managed";
|
|
71
|
+
if (!isOursToManage) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const changed = enabled
|
|
76
|
+
? enableProfile(profiles, profileOrder, previous, isByokMode)
|
|
77
|
+
: disableProfile(llm, profiles, profileOrder, previous);
|
|
78
|
+
|
|
79
|
+
if (changed) {
|
|
80
|
+
saveRawConfig(config);
|
|
81
|
+
invalidateConfigCache();
|
|
82
|
+
log.info(
|
|
83
|
+
{ profile: OS_BETA_PROFILE_KEY, enabled },
|
|
84
|
+
"Reconciled flag-gated profile",
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
return changed;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function enableProfile(
|
|
91
|
+
profiles: Record<string, Record<string, unknown>>,
|
|
92
|
+
profileOrder: string[],
|
|
93
|
+
previous: Record<string, unknown> | null,
|
|
94
|
+
isByokMode: boolean,
|
|
95
|
+
): boolean {
|
|
96
|
+
const effectiveTemplate = isByokMode
|
|
97
|
+
? {
|
|
98
|
+
...OS_BETA_PROFILE_TEMPLATE,
|
|
99
|
+
label: `${OS_BETA_PROFILE_TEMPLATE.label} (Managed)`,
|
|
100
|
+
}
|
|
101
|
+
: OS_BETA_PROFILE_TEMPLATE;
|
|
102
|
+
const next = materializeProfile(
|
|
103
|
+
effectiveTemplate,
|
|
104
|
+
OS_BETA_PROFILE_TEMPLATE.provider,
|
|
105
|
+
OS_BETA_PROFILE_TEMPLATE.connectionName,
|
|
106
|
+
) as Record<string, unknown>;
|
|
107
|
+
|
|
108
|
+
// BYOK installs seed managed profiles disabled: the platform-auth
|
|
109
|
+
// `fireworks-managed` connection backing this profile isn't usable until the
|
|
110
|
+
// user enables it, so a fresh OS Beta entry starts disabled to avoid offering
|
|
111
|
+
// an unusable route. A user's own status override (preserved below) wins on
|
|
112
|
+
// later reconciles.
|
|
113
|
+
if (isByokMode && !previous) {
|
|
114
|
+
next.status = "disabled";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (previous) {
|
|
118
|
+
// The only fields a user may override on a managed profile. Carry `label`
|
|
119
|
+
// by key-presence so an explicit null (user cleared it) survives too.
|
|
120
|
+
if ("label" in previous) next.label = previous.label;
|
|
121
|
+
if ("status" in previous) next.status = previous.status;
|
|
122
|
+
if ("advisorEnabled" in previous) {
|
|
123
|
+
next.advisorEnabled = previous.advisorEnabled;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let changed = false;
|
|
128
|
+
if (!previous || !isDeepStrictEqual(previous, next)) {
|
|
129
|
+
profiles[OS_BETA_PROFILE_KEY] = next as ProfileEntry;
|
|
130
|
+
changed = true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!profileOrder.includes(OS_BETA_PROFILE_KEY)) {
|
|
134
|
+
const balancedIndex = profileOrder.indexOf("balanced");
|
|
135
|
+
if (balancedIndex >= 0) {
|
|
136
|
+
profileOrder.splice(balancedIndex + 1, 0, OS_BETA_PROFILE_KEY);
|
|
137
|
+
} else {
|
|
138
|
+
profileOrder.push(OS_BETA_PROFILE_KEY);
|
|
139
|
+
}
|
|
140
|
+
changed = true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return changed;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// `MixSchema = z.array(MixArmSchema).min(2)` in schemas/llm.ts: mixes require
|
|
147
|
+
// >= 2 arms. A mix that drops below this is invalid and cannot be kept.
|
|
148
|
+
const MIX_MIN_ARMS = 2;
|
|
149
|
+
|
|
150
|
+
function disableProfile(
|
|
151
|
+
llm: Record<string, unknown>,
|
|
152
|
+
profiles: Record<string, Record<string, unknown>>,
|
|
153
|
+
profileOrder: string[],
|
|
154
|
+
previous: Record<string, unknown> | null,
|
|
155
|
+
): boolean {
|
|
156
|
+
if (!previous) return false;
|
|
157
|
+
|
|
158
|
+
delete profiles[OS_BETA_PROFILE_KEY];
|
|
159
|
+
|
|
160
|
+
// The removal closure: every name here is absent from `profiles` once the
|
|
161
|
+
// closure settles, so the written config can never reference one. A mix that
|
|
162
|
+
// loses arms below the >= 2 minimum is itself invalid, so it joins the set
|
|
163
|
+
// and the loop runs to a fixpoint to resolve any references that cascade.
|
|
164
|
+
const removed = new Set<string>([OS_BETA_PROFILE_KEY]);
|
|
165
|
+
let cascading = true;
|
|
166
|
+
while (cascading) {
|
|
167
|
+
cascading = false;
|
|
168
|
+
for (const [name, profile] of Object.entries(profiles)) {
|
|
169
|
+
if (removed.has(name)) continue;
|
|
170
|
+
if (!Array.isArray(profile.mix)) continue;
|
|
171
|
+
const arms = profile.mix as unknown[];
|
|
172
|
+
const kept = arms.filter((arm) => {
|
|
173
|
+
const armProfile = readObject(arm)?.profile;
|
|
174
|
+
return typeof armProfile !== "string" || !removed.has(armProfile);
|
|
175
|
+
});
|
|
176
|
+
if (kept.length === arms.length) continue;
|
|
177
|
+
if (kept.length >= MIX_MIN_ARMS) {
|
|
178
|
+
profile.mix = kept;
|
|
179
|
+
} else {
|
|
180
|
+
delete profiles[name];
|
|
181
|
+
removed.add(name);
|
|
182
|
+
}
|
|
183
|
+
cascading = true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
llm.profileOrder = profileOrder.filter((name) => !removed.has(name));
|
|
188
|
+
|
|
189
|
+
if (typeof llm.activeProfile === "string" && removed.has(llm.activeProfile)) {
|
|
190
|
+
llm.activeProfile = "balanced";
|
|
191
|
+
}
|
|
192
|
+
if (
|
|
193
|
+
typeof llm.advisorProfile === "string" &&
|
|
194
|
+
removed.has(llm.advisorProfile)
|
|
195
|
+
) {
|
|
196
|
+
if (readObject(profiles["quality-optimized"]) !== null) {
|
|
197
|
+
llm.advisorProfile = "quality-optimized";
|
|
198
|
+
} else {
|
|
199
|
+
delete llm.advisorProfile;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Clear any call-site `profile` reference to a removed profile; other override
|
|
204
|
+
// fields on the entry stay intact (an empty override object is valid).
|
|
205
|
+
const callSites = readObject(llm.callSites);
|
|
206
|
+
if (callSites) {
|
|
207
|
+
for (const entry of Object.values(callSites)) {
|
|
208
|
+
const site = readObject(entry);
|
|
209
|
+
if (
|
|
210
|
+
site &&
|
|
211
|
+
typeof site.profile === "string" &&
|
|
212
|
+
removed.has(site.profile)
|
|
213
|
+
) {
|
|
214
|
+
delete site.profile;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return true;
|
|
220
|
+
}
|