@vellumai/assistant 0.11.1 → 0.11.2-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/Dockerfile +1 -3
- package/README.md +1 -1
- package/eslint.config.mjs +28 -8
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +48 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +25 -6
- package/openapi.yaml +292 -5
- package/package.json +1 -1
- package/src/__tests__/agent-loop-resume-interrupted.test.ts +223 -0
- package/src/__tests__/byok-default-profile-ensure.test.ts +43 -0
- package/src/__tests__/cli-logger-boundary-guard.test.ts +87 -0
- package/src/__tests__/compaction-events.test.ts +139 -2
- package/src/__tests__/config-loader-backfill.test.ts +35 -3
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +30 -0
- package/src/__tests__/conversation-agent-loop.test.ts +180 -7
- package/src/__tests__/conversation-error.test.ts +211 -4
- package/src/__tests__/conversation-options-turn-scoped-transport.test.ts +64 -0
- package/src/__tests__/conversation-queue.test.ts +126 -0
- package/src/__tests__/conversation-retry-route.test.ts +46 -7
- package/src/__tests__/conversation-slash.test.ts +4 -2
- package/src/__tests__/conversation-summarize-route.test.ts +7 -1
- package/src/__tests__/conversation-summarize-up-to.test.ts +71 -5
- package/src/__tests__/document-create-dedupe.test.ts +2 -1
- package/src/__tests__/document-find-replace.test.ts +2 -1
- package/src/__tests__/document-tool-security.test.ts +2 -1
- package/src/__tests__/document-update-default-surface.test.ts +2 -1
- package/src/__tests__/document-workspace-file.test.ts +467 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +290 -49
- package/src/__tests__/guardian-card-withdrawal.test.ts +91 -3
- package/src/__tests__/http-user-message-parity.test.ts +66 -0
- package/src/__tests__/list-messages-attachments.test.ts +87 -0
- package/src/__tests__/list-messages-provider-error.test.ts +143 -0
- package/src/__tests__/list-messages-system-card.test.ts +100 -0
- package/src/__tests__/llm-resolver.test.ts +19 -9
- package/src/__tests__/managed-profile-guard.test.ts +23 -0
- package/src/__tests__/notification-platform-adapter.test.ts +130 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +6 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +45 -0
- package/src/__tests__/plugin-api-model-profiles.test.ts +10 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +3 -0
- package/src/__tests__/provider-error-scenarios.test.ts +140 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +95 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +66 -3
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +209 -0
- package/src/__tests__/skills.test.ts +27 -0
- package/src/__tests__/slack-channels-routes.test.ts +0 -2
- package/src/__tests__/slack-share-routes.test.ts +0 -3
- package/src/__tests__/slack-users-routes.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +11 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +58 -0
- package/src/__tests__/tool-result-spool.test.ts +5 -4
- package/src/__tests__/turn-boundary-resolution.test.ts +53 -0
- package/src/__tests__/turn-events-store.test.ts +26 -0
- package/src/__tests__/ui-visual-surface.test.ts +695 -0
- package/src/__tests__/unified-turn-context-visible-app.test.ts +99 -0
- package/src/__tests__/visible-app-context.test.ts +189 -0
- package/src/__tests__/workspace-git-service.test.ts +173 -33
- package/src/__tests__/workspace-migration-137-repair-retired-fireworks-minimax-model-id.test.ts +157 -0
- package/src/__tests__/workspace-migration-138-backfill-home-feed-titles.test.ts +373 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +137 -0
- package/src/agent/loop.ts +36 -7
- package/src/api/events/context-window-usage.ts +31 -0
- package/src/api/events/notification-intent.ts +8 -0
- package/src/api/events/ui-surface-pending.ts +35 -0
- package/src/api/index.ts +14 -0
- package/src/api/responses/conversation-message.ts +25 -4
- package/src/api/surfaces.ts +90 -1
- package/src/approvals/guardian-card-withdrawal.ts +66 -31
- package/src/approvals/guardian-decision-primitive.ts +4 -0
- package/src/calls/__tests__/call-setup-router.test.ts +156 -26
- package/src/calls/__tests__/voice-session-bridge.test.ts +201 -12
- package/src/calls/call-setup-router.ts +80 -36
- package/src/calls/voice-session-bridge.ts +173 -26
- package/src/cli/commands/inference.help.ts +3 -3
- package/src/cli/commands/notifications.help.ts +3 -2
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +42 -128
- package/src/cli/commands/platform/__tests__/credits.test.ts +9 -78
- package/src/cli/commands/platform/__tests__/helpers.ts +90 -0
- package/src/cli/commands/platform/__tests__/invoices.test.ts +238 -0
- package/src/cli/commands/platform/__tests__/plans.test.ts +9 -88
- package/src/cli/commands/platform/__tests__/status.test.ts +12 -87
- package/src/cli/commands/platform/__tests__/subscription.test.ts +9 -86
- package/src/cli/commands/platform/index.help.ts +92 -0
- package/src/cli/commands/platform/index.ts +7 -0
- package/src/cli/commands/platform/invoices.ts +132 -0
- package/src/cli/commands/usage.help.ts +1 -1
- package/src/cli/lib/list-installed-plugins.ts +2 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +7 -10
- package/src/config/__tests__/deployment-context-defaults.test.ts +27 -5
- package/src/config/assistant-feature-flags.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -2
- package/src/config/bundled-skills/subagent/SKILL.md +3 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +3 -3
- package/src/config/bundled-skills/visualize/SKILL.md +163 -0
- package/src/config/call-site-defaults.ts +3 -2
- package/src/config/default-profile-catalog.ts +75 -70
- package/src/config/default-profile-names.ts +13 -28
- package/src/config/env-registry.ts +1 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +21 -5
- package/src/config/loader.ts +18 -11
- package/src/config/schemas/llm.ts +1 -9
- package/src/config/schemas/memory-retrospective.ts +9 -0
- package/src/config/schemas/monitoring.ts +28 -2
- package/src/config/schemas/workspace-git.ts +15 -0
- package/src/config/seed-inference-profiles.ts +19 -5
- package/src/context/post-turn-tool-result-truncation.ts +2 -2
- package/src/conversations/__tests__/message-consolidation.test.ts +54 -0
- package/src/conversations/message-consolidation.ts +17 -15
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +182 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +181 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +90 -7
- package/src/daemon/conversation-agent-loop.ts +107 -22
- package/src/daemon/conversation-error.ts +169 -48
- package/src/daemon/conversation-messaging.ts +87 -4
- package/src/daemon/conversation-process.ts +57 -45
- package/src/daemon/conversation-runtime-assembly.ts +57 -0
- package/src/daemon/conversation-store.ts +36 -1
- package/src/daemon/conversation-surfaces.ts +68 -6
- package/src/daemon/conversation-turn-finalize.ts +76 -18
- package/src/daemon/conversation.ts +122 -27
- package/src/daemon/lifecycle.ts +9 -0
- package/src/daemon/message-types/conversations.ts +8 -0
- package/src/daemon/message-types/surfaces.ts +3 -0
- package/src/documents/document-store.ts +247 -10
- package/src/home/__tests__/feed-types.test.ts +43 -8
- package/src/home/__tests__/feed-writer.test.ts +59 -0
- package/src/home/feed-types.ts +34 -7
- package/src/home/feed-writer.ts +15 -6
- package/src/live-voice/__tests__/activity-label.test.ts +95 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +86 -5
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +310 -25
- package/src/live-voice/__tests__/live-voice-events.test.ts +4 -4
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +8 -4
- package/src/live-voice/__tests__/live-voice-vad.test.ts +9 -1
- package/src/live-voice/activity-label.ts +169 -0
- package/src/live-voice/live-activity-reporter.ts +35 -6
- package/src/live-voice/live-voice-session.ts +282 -41
- package/src/live-voice/protocol.ts +35 -0
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +84 -2
- package/src/messaging/providers/slack/adapter.ts +86 -19
- package/src/messaging/providers/slack/api.test.ts +85 -1
- package/src/messaging/providers/slack/api.ts +121 -288
- package/src/messaging/providers/slack/client.ts +20 -251
- package/src/messaging/providers/slack/send.test.ts +4 -9
- package/src/messaging/providers/slack/send.ts +1 -1
- package/src/messaging/providers/slack/types.ts +5 -0
- package/src/messaging/providers/slack/web-api-transport.test.ts +181 -0
- package/src/messaging/providers/slack/web-api-transport.ts +367 -0
- package/src/messaging/providers/slack/withdraw.ts +6 -14
- package/src/messaging/providers/telegram-bot/send.test.ts +31 -1
- package/src/messaging/providers/telegram-bot/send.ts +23 -2
- package/src/messaging/providers/telegram-bot/withdraw.test.ts +152 -0
- package/src/messaging/providers/telegram-bot/withdraw.ts +166 -0
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +18 -4
- package/src/monitoring/__tests__/file-descriptors.test.ts +144 -0
- package/src/monitoring/file-descriptors.ts +262 -0
- package/src/monitoring/process-memory.ts +4 -11
- package/src/monitoring/resource-sampler.ts +5 -0
- package/src/monitoring/worker.ts +12 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +740 -0
- package/src/notifications/__tests__/broadcaster.test.ts +347 -7
- package/src/notifications/__tests__/copy-composer.test.ts +53 -3
- package/src/notifications/__tests__/decision-engine.test.ts +349 -29
- package/src/notifications/__tests__/deterministic-checks.test.ts +21 -0
- package/src/notifications/__tests__/edit-notification.test.ts +330 -0
- package/src/notifications/__tests__/guardian-delivery-recorder.test.ts +71 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +170 -12
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/adapters/platform.ts +90 -14
- package/src/notifications/adapters/telegram.ts +6 -4
- package/src/notifications/assistant-reply-producer.ts +219 -0
- package/src/notifications/broadcaster.ts +523 -317
- package/src/notifications/copy-composer.ts +27 -6
- package/src/notifications/decision-engine.ts +154 -77
- package/src/notifications/deterministic-checks.ts +6 -7
- package/src/notifications/edit-notification.ts +8 -4
- package/src/notifications/emit-signal.ts +49 -16
- package/src/notifications/guardian-delivery-recorder.ts +8 -2
- package/src/notifications/home-feed-side-effect.ts +43 -6
- package/src/notifications/notification-utils.ts +39 -4
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +17 -0
- package/src/persistence/bookmark-crud.ts +18 -9
- package/src/persistence/conversation-attention-store.ts +26 -0
- package/src/persistence/conversation-crud.ts +79 -32
- package/src/persistence/conversation-queries.ts +30 -15
- package/src/persistence/conversation-title-service.ts +5 -170
- package/src/persistence/conversation-types.ts +192 -1
- package/src/persistence/db-init.ts +14 -1
- package/src/persistence/db-maintenance.ts +5 -4
- package/src/persistence/embeddings/__tests__/plugin-index-qdrant-init.test.ts +219 -0
- package/src/persistence/embeddings/__tests__/plugin-index.test.ts +22 -0
- package/src/persistence/embeddings/__tests__/worker-script-version.test.ts +76 -0
- package/src/persistence/embeddings/embedding-local.ts +2 -1
- package/src/persistence/embeddings/embedding-runtime-manager.ts +29 -5
- package/src/persistence/embeddings/plugin-index.ts +84 -12
- package/src/persistence/migrations/360-add-document-workspace-path.test.ts +110 -0
- package/src/persistence/migrations/360-add-document-workspace-path.ts +39 -0
- package/src/persistence/planner-statistics.ts +14 -0
- package/src/persistence/schema/documents.ts +26 -11
- package/src/persistence/steps.ts +2 -0
- package/src/platform/client.test.ts +172 -2
- package/src/platform/client.ts +178 -55
- package/src/plugin-api/conversation-turn.ts +13 -0
- package/src/plugin-api/model-profiles.test.ts +6 -2
- package/src/plugins/defaults/memory/__tests__/bookmark-crud.test.ts +34 -0
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +22 -0
- package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +11 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +199 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +98 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +105 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +24 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +524 -0
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +9 -4
- package/src/plugins/defaults/memory/host-utils.ts +5 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +105 -1
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +64 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +36 -1
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +12 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +1 -0
- package/src/plugins/defaults/memory/substrate/__tests__/skill-store.test.ts +195 -1
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +1 -1
- package/src/plugins/defaults/memory/substrate/skill-store.ts +167 -29
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +131 -0
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +1 -0
- package/src/plugins/defaults/memory/v2/activation-log-store.ts +4 -0
- package/src/plugins/defaults/memory/v2/injection.ts +48 -3
- package/src/plugins/defaults/memory/v2/rerank-local.ts +6 -2
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -1
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +1 -1
- package/src/plugins/defaults/turn-context/injectors.ts +1 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +26 -0
- package/src/plugins/types.ts +17 -0
- package/src/prompts/templates/system-sections.ts +2 -2
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +43 -2
- package/src/providers/__tests__/vellum-mismatch-routing.test.ts +8 -0
- package/src/providers/call-site-routing.ts +77 -14
- package/src/providers/connection-resolution.ts +42 -2
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +127 -1
- package/src/providers/inference/adapter-factory.ts +70 -12
- package/src/providers/model-catalog.ts +0 -11
- package/src/providers/model-intents.ts +11 -0
- package/src/providers/registry.ts +8 -0
- package/src/providers/retry.ts +85 -17
- package/src/providers/types.ts +8 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/agent-wake.ts +132 -9
- package/src/runtime/channel-approval-types.ts +25 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +2 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +11 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +121 -9
- package/src/runtime/routes/__tests__/platform-invoice-routes.test.ts +392 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +7 -0
- package/src/runtime/routes/__tests__/workspace-commit-routes.test.ts +63 -0
- package/src/runtime/routes/consolidation-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +18 -6
- package/src/runtime/routes/conversation-query-routes.ts +14 -23
- package/src/runtime/routes/conversation-routes.ts +113 -8
- package/src/runtime/routes/credential-routes.ts +1 -5
- package/src/runtime/routes/documents-routes.ts +207 -12
- package/src/runtime/routes/identity-routes.ts +3 -93
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +31 -1
- package/src/runtime/routes/inbound-stages/admission-policy.ts +18 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +52 -3
- package/src/runtime/routes/notification-routes.ts +4 -1
- package/src/runtime/routes/platform-routes.ts +238 -3
- package/src/runtime/routes/playground/guard.ts +1 -2
- package/src/runtime/routes/slack-channel-routes.ts +2 -4
- package/src/runtime/routes/workspace-commit-routes.ts +49 -2
- package/src/runtime/routes/workspace-routes.ts +11 -12
- package/src/runtime/routes/workspace-utils.ts +49 -2
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/subagent/__tests__/consult-context-gating.test.ts +98 -0
- package/src/subagent/__tests__/consult-context-skills.test.ts +82 -0
- package/src/subagent/__tests__/consult-context.test.ts +84 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +36 -0
- package/src/subagent/consult-context.ts +410 -0
- package/src/subagent/consult-prompt.ts +38 -5
- package/src/subagent/manager.ts +9 -4
- package/src/subagent/types.ts +8 -0
- package/src/telemetry/telemetry-event-sources.ts +7 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +1 -0
- package/src/telemetry/turn-events-store.ts +30 -1
- package/src/telemetry/types.ts +24 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/tools/browser/pinned-tabs.ts +3 -1
- package/src/tools/subagent/spawn.ts +23 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/ui-surface/definitions.ts +39 -1
- package/src/tools/ui-surface/surface-shape-docs.ts +38 -4
- package/src/tools/ui-surface/visual-validation.ts +787 -0
- package/src/tools/workflows/run-workflow.test.ts +1 -0
- package/src/util/__tests__/short-title.test.ts +229 -0
- package/src/util/__tests__/worker-compute.test.ts +65 -0
- package/src/util/cgroup-cpu.ts +93 -0
- package/src/util/errors.ts +27 -0
- package/src/util/process-tree.ts +19 -0
- package/src/util/short-title.ts +189 -0
- package/src/util/worker-compute.ts +83 -0
- package/src/workspace/byok-default-profile-ensure.ts +25 -15
- package/src/workspace/git-service.ts +79 -30
- package/src/workspace/migrations/137-repair-retired-fireworks-minimax-model-id.ts +131 -0
- package/src/workspace/migrations/138-backfill-home-feed-titles.ts +179 -0
- package/src/workspace/migrations/139-clear-renamed-cost-profile-label.ts +92 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/plugins/defaults/memory/substrate/constants.ts +0 -8
|
@@ -11,12 +11,8 @@ import {
|
|
|
11
11
|
DEFAULT_PROFILE_PROVIDERS,
|
|
12
12
|
type DefaultProfileKey,
|
|
13
13
|
type DefaultProfileProvider,
|
|
14
|
-
INTERNAL_PROFILE_KEYS,
|
|
15
|
-
type InternalProfileKey,
|
|
16
14
|
isDefaultProfileProvider,
|
|
17
15
|
OS_BETA_PROFILE_KEY,
|
|
18
|
-
PROFILE_MATRIX_KEYS,
|
|
19
|
-
type ProfileMatrixKey,
|
|
20
16
|
} from "./default-profile-names.js";
|
|
21
17
|
import { resolveDefaultConnectionName } from "./default-provider-resolution.js";
|
|
22
18
|
import {
|
|
@@ -28,7 +24,8 @@ import {
|
|
|
28
24
|
|
|
29
25
|
/**
|
|
30
26
|
* Code-defined catalog of the default inference profiles (`balanced`,
|
|
31
|
-
* `quality-optimized`, `cost-optimized`, plus the
|
|
27
|
+
* `quality-optimized`, `cost-optimized`, `latency-optimized`, plus the
|
|
28
|
+
* flag-gated `os-beta`).
|
|
32
29
|
*
|
|
33
30
|
* The catalog is the single source of truth for default profile CONTENT,
|
|
34
31
|
* structured as an intent × provider matrix: each default profile is an
|
|
@@ -60,6 +57,9 @@ export type DefaultProfileTemplate = Omit<
|
|
|
60
57
|
provider: NonNullable<ProfileEntry["provider"]>;
|
|
61
58
|
};
|
|
62
59
|
|
|
60
|
+
/** One implementation of every default profile, keyed by profile key. */
|
|
61
|
+
type ProfileImpls = Record<DefaultProfileKey, DefaultProfileTemplate>;
|
|
62
|
+
|
|
63
63
|
/**
|
|
64
64
|
* The `vellum` column: platform-managed implementations, stamped
|
|
65
65
|
* `provider: "vellum"` — dispatch derives the upstream from the model.
|
|
@@ -68,7 +68,7 @@ export type DefaultProfileTemplate = Omit<
|
|
|
68
68
|
* Overwritten in workspace config on every daemon boot so Vellum can push
|
|
69
69
|
* model/config updates to customers in new releases.
|
|
70
70
|
*/
|
|
71
|
-
const VELLUM_PROFILE_IMPLS:
|
|
71
|
+
const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
72
72
|
balanced: {
|
|
73
73
|
model: "gpt-5.6-luna",
|
|
74
74
|
provider: "vellum",
|
|
@@ -99,11 +99,11 @@ const VELLUM_PROFILE_IMPLS: Record<ProfileMatrixKey, DefaultProfileTemplate> = {
|
|
|
99
99
|
model: "accounts/fireworks/models/deepseek-v4-flash",
|
|
100
100
|
provider: "vellum",
|
|
101
101
|
source: "managed",
|
|
102
|
-
label: "
|
|
102
|
+
label: "Cost",
|
|
103
103
|
// Tier intent only - never name the concrete model here. Clients
|
|
104
104
|
// surface the live model beside the description, so a model name in
|
|
105
105
|
// this copy would go stale the moment the pin moves.
|
|
106
|
-
description: "
|
|
106
|
+
description: "Cheapest responses, for high-volume work",
|
|
107
107
|
maxTokens: 8192,
|
|
108
108
|
// Explicit reasoning opt-out. OpenAI-compat APIs default reasoning to
|
|
109
109
|
// "medium" when the field is omitted, and effort-driven providers encode
|
|
@@ -116,22 +116,24 @@ const VELLUM_PROFILE_IMPLS: Record<ProfileMatrixKey, DefaultProfileTemplate> = {
|
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
118
|
"latency-optimized": {
|
|
119
|
-
// The managed latency class
|
|
120
|
-
// turn-taking verdict, so what this profile
|
|
121
|
-
// time-to-first-token rather than the median: a
|
|
122
|
-
// `liveVoice.frontModel.endpointDecisionTimeoutMs`
|
|
123
|
-
// fail-open commit in live-voice-session.ts, which
|
|
119
|
+
// The managed latency class, also what the live-voice front model runs on.
|
|
120
|
+
// Its leading tokens are the turn-taking verdict, so what this profile
|
|
121
|
+
// optimizes is the tail of time-to-first-token rather than the median: a
|
|
122
|
+
// verdict slower than `liveVoice.frontModel.endpointDecisionTimeoutMs`
|
|
123
|
+
// trips the speculative fail-open commit in live-voice-session.ts, which
|
|
124
|
+
// is audible dead air.
|
|
124
125
|
//
|
|
125
126
|
// Two constraints bind the model id. Its managed credentials must be
|
|
126
127
|
// provisioned in every environment, and it alone selects the upstream:
|
|
127
128
|
// `provider` below is the provider-agnostic managed sentinel, so
|
|
128
129
|
// `getManagedUpstream` resolves the real upstream from the model's catalog
|
|
129
|
-
// owner.
|
|
130
|
+
// owner. Sharing `balanced`'s model is deliberate: the split is effort
|
|
131
|
+
// and thinking, and this model is the one live-voice TTFT drives validated.
|
|
130
132
|
model: "gpt-5.6-luna",
|
|
131
133
|
provider: "vellum",
|
|
132
134
|
source: "managed",
|
|
133
|
-
label: "
|
|
134
|
-
description: "
|
|
135
|
+
label: "Speed",
|
|
136
|
+
description: "Fastest responses, with reasoning turned off",
|
|
135
137
|
maxTokens: 8192,
|
|
136
138
|
effort: "low",
|
|
137
139
|
thinking: { enabled: false, streamThinking: false },
|
|
@@ -150,7 +152,7 @@ const VELLUM_PROFILE_IMPLS: Record<ProfileMatrixKey, DefaultProfileTemplate> = {
|
|
|
150
152
|
* per-request for any other default-capable provider.
|
|
151
153
|
*/
|
|
152
154
|
const BYOK_PROFILE_IMPLS: Record<
|
|
153
|
-
|
|
155
|
+
DefaultProfileKey,
|
|
154
156
|
Omit<DefaultProfileTemplate, "provider">
|
|
155
157
|
> = {
|
|
156
158
|
balanced: {
|
|
@@ -173,21 +175,24 @@ const BYOK_PROFILE_IMPLS: Record<
|
|
|
173
175
|
thinking: { enabled: true, streamThinking: true },
|
|
174
176
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
175
177
|
},
|
|
178
|
+
// On providers whose cheapest model is also their fastest (anthropic,
|
|
179
|
+
// ollama, fireworks) these two intents resolve the same model and the split
|
|
180
|
+
// is effort alone (see PROVIDER_MODEL_INTENTS).
|
|
176
181
|
"cost-optimized": {
|
|
177
|
-
intent: "
|
|
182
|
+
intent: "cost-optimized",
|
|
178
183
|
source: "user",
|
|
179
|
-
label: "
|
|
180
|
-
description: "
|
|
184
|
+
label: "Cost",
|
|
185
|
+
description: "Cheapest responses, for high-volume work",
|
|
181
186
|
maxTokens: 8192,
|
|
182
|
-
effort: "
|
|
187
|
+
effort: "none",
|
|
183
188
|
thinking: { enabled: false, streamThinking: false },
|
|
184
189
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
185
190
|
},
|
|
186
191
|
"latency-optimized": {
|
|
187
192
|
intent: "latency-optimized",
|
|
188
193
|
source: "user",
|
|
189
|
-
label: "
|
|
190
|
-
description: "
|
|
194
|
+
label: "Speed",
|
|
195
|
+
description: "Fastest responses, with reasoning turned off",
|
|
191
196
|
maxTokens: 8192,
|
|
192
197
|
effort: "low",
|
|
193
198
|
thinking: { enabled: false, streamThinking: false },
|
|
@@ -200,10 +205,10 @@ const BYOK_PROFILE_IMPLS: Record<
|
|
|
200
205
|
* implementation of default profile `key` on `provider`.
|
|
201
206
|
*/
|
|
202
207
|
export const PROFILE_IMPLS: Record<
|
|
203
|
-
|
|
208
|
+
DefaultProfileKey,
|
|
204
209
|
Record<DefaultProfileProvider, DefaultProfileTemplate>
|
|
205
210
|
> = Object.fromEntries(
|
|
206
|
-
|
|
211
|
+
DEFAULT_PROFILE_KEYS.map((key) => [
|
|
207
212
|
key,
|
|
208
213
|
Object.fromEntries(
|
|
209
214
|
DEFAULT_PROFILE_PROVIDERS.map((provider) => [
|
|
@@ -215,7 +220,7 @@ export const PROFILE_IMPLS: Record<
|
|
|
215
220
|
) as Record<DefaultProfileProvider, DefaultProfileTemplate>,
|
|
216
221
|
]),
|
|
217
222
|
) as Record<
|
|
218
|
-
|
|
223
|
+
DefaultProfileKey,
|
|
219
224
|
Record<DefaultProfileProvider, DefaultProfileTemplate>
|
|
220
225
|
>;
|
|
221
226
|
|
|
@@ -229,18 +234,45 @@ export const MANAGED_PROFILE_TEMPLATES: Record<string, DefaultProfileTemplate> =
|
|
|
229
234
|
DEFAULT_PROFILE_KEYS.map((key) => [key, PROFILE_IMPLS[key].vellum]),
|
|
230
235
|
);
|
|
231
236
|
|
|
237
|
+
/**
|
|
238
|
+
* The values BYOK hatch seeding wrote onto each `custom-*` copy, for the keys
|
|
239
|
+
* whose live template carries something else. The conversion pass recognizes
|
|
240
|
+
* an unedited copy by comparing it field-by-field against the frozen body, so
|
|
241
|
+
* every field here must describe what sits on disk, not what the profile
|
|
242
|
+
* resolves to today. A field the live template alone supplies makes every
|
|
243
|
+
* unedited copy read as user-edited and stop converting.
|
|
244
|
+
*
|
|
245
|
+
* `intent` selects the copy's model through `materializeProfile`, so it is the
|
|
246
|
+
* load-bearing pin. `label` is compared nowhere in the body, but
|
|
247
|
+
* `userOverlayState` reads it to tell a user rename from the hatch's own
|
|
248
|
+
* label, and a mismatch there carries a phantom rename onto the bare key.
|
|
249
|
+
*/
|
|
250
|
+
const HATCH_ERA_TEMPLATE_FIELDS: Partial<
|
|
251
|
+
Record<DefaultProfileKey, Partial<DefaultProfileTemplate>>
|
|
252
|
+
> = {
|
|
253
|
+
"cost-optimized": {
|
|
254
|
+
intent: "latency-optimized",
|
|
255
|
+
label: "Speed",
|
|
256
|
+
description: "Fastest responses at lower cost",
|
|
257
|
+
effort: "low",
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
|
|
232
261
|
/**
|
|
233
262
|
* Frozen record of the `custom-*` profile bodies that pre-conversion BYOK
|
|
234
263
|
* hatches wrote to workspace config (the anthropic column; provider and
|
|
235
264
|
* connection were overridden per hatch). Consumed by the existing-install
|
|
236
265
|
* conversion pass as the reference for recognizing unedited copies, which
|
|
237
266
|
* are safe to remove in favor of the code-resolved defaults.
|
|
267
|
+
*
|
|
268
|
+
* The `latency-optimized` entry exists for shape only: hatch seeding writes no
|
|
269
|
+
* `custom-latency-optimized`, so no install holds one to recognize.
|
|
238
270
|
*/
|
|
239
271
|
export const USER_PROFILE_TEMPLATES: Record<string, DefaultProfileTemplate> =
|
|
240
272
|
Object.fromEntries(
|
|
241
273
|
DEFAULT_PROFILE_KEYS.map((key) => [
|
|
242
274
|
`custom-${key}`,
|
|
243
|
-
PROFILE_IMPLS[key].anthropic,
|
|
275
|
+
{ ...PROFILE_IMPLS[key].anthropic, ...HATCH_ERA_TEMPLATE_FIELDS[key] },
|
|
244
276
|
]),
|
|
245
277
|
);
|
|
246
278
|
|
|
@@ -263,6 +295,17 @@ export const OS_BETA_PROFILE_TEMPLATE: DefaultProfileTemplate = {
|
|
|
263
295
|
topP: 0.95,
|
|
264
296
|
};
|
|
265
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Profiles whose body is code-owned outright: no workspace overlay, and no
|
|
300
|
+
* user-owned shadow. The shadow rule below lets a user replace a default they
|
|
301
|
+
* can select, but `latency-optimized` fronts every live-voice turn through
|
|
302
|
+
* `voiceFrontDecision`/`voiceFrontDoor`, where a model outside the latency
|
|
303
|
+
* envelope is audible dead air rather than a slow reply. A same-named
|
|
304
|
+
* workspace entry stays on disk and stays listed; it just never governs what
|
|
305
|
+
* this name resolves to.
|
|
306
|
+
*/
|
|
307
|
+
export const CODE_OWNED_PROFILE_NAMES = new Set<string>(["latency-optimized"]);
|
|
308
|
+
|
|
266
309
|
// All managed profiles, including the flag-gated os-beta, are invariant:
|
|
267
310
|
// their MANAGED-SOURCE entries are read-only to user-facing writes except
|
|
268
311
|
// re-enabling a disabled one (enforced at commitConfigWrite). A user-owned
|
|
@@ -270,7 +313,6 @@ export const OS_BETA_PROFILE_TEMPLATE: DefaultProfileTemplate = {
|
|
|
270
313
|
// the on-disk entry's `source` being `managed`.
|
|
271
314
|
export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
272
315
|
...DEFAULT_PROFILE_KEYS,
|
|
273
|
-
...INTERNAL_PROFILE_KEYS,
|
|
274
316
|
OS_BETA_PROFILE_KEY,
|
|
275
317
|
]);
|
|
276
318
|
|
|
@@ -283,7 +325,6 @@ export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
|
283
325
|
// same-named user profile.
|
|
284
326
|
export const MANAGED_PROFILE_NAMES = new Set<string>([
|
|
285
327
|
...DEFAULT_PROFILE_KEYS,
|
|
286
|
-
...INTERNAL_PROFILE_KEYS,
|
|
287
328
|
OS_BETA_PROFILE_KEY,
|
|
288
329
|
]);
|
|
289
330
|
|
|
@@ -319,7 +360,7 @@ export function materializeProfile(
|
|
|
319
360
|
// `PROVIDER_MODEL_INTENTS`' own check): exactly one of `intent`/`model` is
|
|
320
361
|
// set, and every pinned model id exists in PROVIDER_CATALOG for its
|
|
321
362
|
// underlying provider — catching drift when a model is renamed or removed.
|
|
322
|
-
for (const key of
|
|
363
|
+
for (const key of DEFAULT_PROFILE_KEYS) {
|
|
323
364
|
for (const provider of DEFAULT_PROFILE_PROVIDERS) {
|
|
324
365
|
const impl = PROFILE_IMPLS[key][provider];
|
|
325
366
|
if ((impl.model == null) === (impl.intent == null)) {
|
|
@@ -355,7 +396,7 @@ for (const provider of DEFAULT_PROVIDER_CHOICES) {
|
|
|
355
396
|
if (isDefaultProfileProvider(provider)) {
|
|
356
397
|
continue;
|
|
357
398
|
}
|
|
358
|
-
for (const key of
|
|
399
|
+
for (const key of DEFAULT_PROFILE_KEYS) {
|
|
359
400
|
const { model } = materializeProfile(
|
|
360
401
|
{ ...BYOK_PROFILE_IMPLS[key], provider },
|
|
361
402
|
provider,
|
|
@@ -372,7 +413,7 @@ for (const provider of DEFAULT_PROVIDER_CHOICES) {
|
|
|
372
413
|
|
|
373
414
|
function buildDefaultProfileEntries(): Record<string, ProfileEntry> {
|
|
374
415
|
const entries: Record<string, ProfileEntry> = {};
|
|
375
|
-
for (const key of
|
|
416
|
+
for (const key of DEFAULT_PROFILE_KEYS) {
|
|
376
417
|
const impl = PROFILE_IMPLS[key].vellum;
|
|
377
418
|
entries[key] = materializeProfile(impl, impl.provider);
|
|
378
419
|
}
|
|
@@ -445,15 +486,7 @@ function resolveAgainstBody(
|
|
|
445
486
|
if (body == null) {
|
|
446
487
|
return workspace;
|
|
447
488
|
}
|
|
448
|
-
|
|
449
|
-
// not even a user-owned shadow. The shadow rule below exists so a user can
|
|
450
|
-
// deliberately replace a default they can see and select; an internal name
|
|
451
|
-
// was never selectable, so a same-named workspace entry (legal before the
|
|
452
|
-
// name was reserved) is unrelated state, not an override. Honoring it would
|
|
453
|
-
// silently hand a latency-class call site an arbitrary user model. The
|
|
454
|
-
// entry itself is untouched: it stays in `llm.profiles`, stays listed, and
|
|
455
|
-
// stays valid as an `activeProfile` reference.
|
|
456
|
-
if (isInternalProfileKey(name)) {
|
|
489
|
+
if (CODE_OWNED_PROFILE_NAMES.has(name)) {
|
|
457
490
|
return { ...body };
|
|
458
491
|
}
|
|
459
492
|
if (workspace == null) {
|
|
@@ -506,27 +539,11 @@ export function isDefaultProfileKey(name: string): name is DefaultProfileKey {
|
|
|
506
539
|
return (DEFAULT_PROFILE_KEYS as readonly string[]).includes(name);
|
|
507
540
|
}
|
|
508
541
|
|
|
509
|
-
/**
|
|
510
|
-
* Whether a name is implemented by the intent × provider matrix — the
|
|
511
|
-
* user-facing defaults plus the internal call-site-only profiles. This is the
|
|
512
|
-
* predicate resolution uses: an internal profile must resolve through the
|
|
513
|
-
* default provider's column exactly like a default, even though it is never
|
|
514
|
-
* listed or seeded.
|
|
515
|
-
*/
|
|
516
|
-
export function isMatrixProfileKey(name: string): name is ProfileMatrixKey {
|
|
517
|
-
return (PROFILE_MATRIX_KEYS as readonly string[]).includes(name);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
/** Whether a name is a code-owned profile that must never be listed to users. */
|
|
521
|
-
export function isInternalProfileKey(name: string): name is InternalProfileKey {
|
|
522
|
-
return (INTERNAL_PROFILE_KEYS as readonly string[]).includes(name);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
542
|
function defaultProfileBodyForProvider(
|
|
526
543
|
name: string,
|
|
527
544
|
defaultProvider: DefaultProviderConfig | null,
|
|
528
545
|
): ProfileEntry | undefined {
|
|
529
|
-
if (defaultProvider == null || !
|
|
546
|
+
if (defaultProvider == null || !isDefaultProfileKey(name)) {
|
|
530
547
|
return CODE_DEFAULT_PROFILE_ENTRIES[name];
|
|
531
548
|
}
|
|
532
549
|
const { provider } = defaultProvider;
|
|
@@ -569,12 +586,6 @@ function clampMaxTokensToModelCap(body: ProfileEntry): ProfileEntry {
|
|
|
569
586
|
* available code default, merged per `getEffectiveProfile`. This is the
|
|
570
587
|
* record all runtime readers of `llm.profiles` should consume; the raw
|
|
571
588
|
* workspace record is a write-path concern.
|
|
572
|
-
*
|
|
573
|
-
* Internal profiles are omitted: they exist only to be named by a call-site
|
|
574
|
-
* default, so listing them would offer them as selectable models and let
|
|
575
|
-
* `activeProfile`/`overrideProfile` validation accept them. Resolution
|
|
576
|
-
* reaches them by name through `resolveDefaultProfileForProvider`, which
|
|
577
|
-
* does not go through this record.
|
|
578
589
|
*/
|
|
579
590
|
export function getEffectiveProfiles(
|
|
580
591
|
workspaceProfiles: Record<string, ProfileEntry> | undefined,
|
|
@@ -586,9 +597,6 @@ export function getEffectiveProfiles(
|
|
|
586
597
|
...(workspaceProfiles ?? {}),
|
|
587
598
|
};
|
|
588
599
|
for (const name of Object.keys(catalogEntries)) {
|
|
589
|
-
if (isInternalProfileKey(name)) {
|
|
590
|
-
continue;
|
|
591
|
-
}
|
|
592
600
|
const entry = getEffectiveProfile(workspaceProfiles, name, catalogEntries);
|
|
593
601
|
if (entry != null) {
|
|
594
602
|
effective[name] = entry;
|
|
@@ -613,9 +621,6 @@ export function getEffectiveProfilesForProvider(
|
|
|
613
621
|
...(workspaceProfiles ?? {}),
|
|
614
622
|
};
|
|
615
623
|
for (const name of Object.keys(CODE_DEFAULT_PROFILE_ENTRIES)) {
|
|
616
|
-
if (isInternalProfileKey(name)) {
|
|
617
|
-
continue;
|
|
618
|
-
}
|
|
619
624
|
const entry = resolveDefaultProfileForProvider(
|
|
620
625
|
workspaceProfiles,
|
|
621
626
|
name,
|
|
@@ -6,41 +6,26 @@
|
|
|
6
6
|
* import cycles.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Stable keys of the always-available default profiles, in picker order.
|
|
11
|
+
*
|
|
12
|
+
* A key is an on-disk contract: `llm.callSites.*.profile`, `activeProfile`,
|
|
13
|
+
* mix arms and schedule pins all reference it, so a key is fixed regardless of
|
|
14
|
+
* the label its profile carries. `cost-optimized` is labelled "Cost" and
|
|
15
|
+
* `latency-optimized` is labelled "Speed" (see `default-profile-catalog.ts`).
|
|
16
|
+
*
|
|
17
|
+
* `latency-optimized` also backs the live-voice front model, which is why it
|
|
18
|
+
* exists as a profile rather than a raw model pin on the call site: a pin
|
|
19
|
+
* resolves to a provider BYOK installs may hold no credential for.
|
|
20
|
+
*/
|
|
10
21
|
export const DEFAULT_PROFILE_KEYS = [
|
|
11
22
|
"balanced",
|
|
12
23
|
"quality-optimized",
|
|
13
24
|
"cost-optimized",
|
|
25
|
+
"latency-optimized",
|
|
14
26
|
] as const;
|
|
15
27
|
export type DefaultProfileKey = (typeof DEFAULT_PROFILE_KEYS)[number];
|
|
16
28
|
|
|
17
|
-
/**
|
|
18
|
-
* Code-owned profiles that exist only to be named by a call-site default —
|
|
19
|
-
* never offered as a user-selectable model. They resolve through the same
|
|
20
|
-
* intent × provider matrix as the defaults, but are deliberately excluded
|
|
21
|
-
* from the workspace seed and from every profile listing, so the picker
|
|
22
|
-
* still shows exactly Balanced / Speed / Quality.
|
|
23
|
-
*
|
|
24
|
-
* `latency-optimized` is the latency-class profile the live-voice front
|
|
25
|
-
* model runs on: `cost-optimized`'s upstream cannot meet the turn-taking
|
|
26
|
-
* latency envelope, and the alternative — a raw model pin on the call site —
|
|
27
|
-
* resolves to a provider BYOK installs may hold no credential for.
|
|
28
|
-
*/
|
|
29
|
-
export const INTERNAL_PROFILE_KEYS = ["latency-optimized"] as const;
|
|
30
|
-
export type InternalProfileKey = (typeof INTERNAL_PROFILE_KEYS)[number];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Every key implemented by the intent × provider matrix: the user-selectable
|
|
34
|
-
* defaults plus the internal call-site-only profiles. This is the set the
|
|
35
|
-
* resolver dereferences against; `DEFAULT_PROFILE_KEYS` alone is the
|
|
36
|
-
* user-facing subset.
|
|
37
|
-
*/
|
|
38
|
-
export const PROFILE_MATRIX_KEYS = [
|
|
39
|
-
...DEFAULT_PROFILE_KEYS,
|
|
40
|
-
...INTERNAL_PROFILE_KEYS,
|
|
41
|
-
] as const;
|
|
42
|
-
export type ProfileMatrixKey = DefaultProfileKey | InternalProfileKey;
|
|
43
|
-
|
|
44
29
|
/**
|
|
45
30
|
* Flag-gated default profile: only available while the `os-beta` feature
|
|
46
31
|
* flag has reconciled it into the workspace (see `sync-gated-profiles.ts`).
|
|
@@ -341,6 +341,14 @@
|
|
|
341
341
|
"description": "Persist chat secret redactions as sentinel markers instead of the legacy HTML marker, enriched with the vault identity when the value byte-matches a credential revealed this turn. Also gates the `credentials reveal --for-chat` channel and the live-stream swap that replaces an echoed reveal plaintext with its sentinel before emission. Redaction itself is NOT gated: a route-proven reveal plaintext stays out of persisted rows in both modes. Client chip rendering is gated on daemon version, not on this flag.",
|
|
342
342
|
"defaultEnabled": false
|
|
343
343
|
},
|
|
344
|
+
{
|
|
345
|
+
"id": "assistant-switcher",
|
|
346
|
+
"scope": "client",
|
|
347
|
+
"key": "assistant-switcher",
|
|
348
|
+
"label": "Assistant Switcher",
|
|
349
|
+
"description": "Show the Switch Assistant section in General settings (local mode only), linking to the assistant chooser.",
|
|
350
|
+
"defaultEnabled": false
|
|
351
|
+
},
|
|
344
352
|
{
|
|
345
353
|
"id": "marketing-pricing-takeover",
|
|
346
354
|
"scope": "client",
|
|
@@ -348,6 +356,14 @@
|
|
|
348
356
|
"label": "Marketing Pricing Takeover",
|
|
349
357
|
"description": "Gates the marketing pricing takeover page (www.vellum.ai/pricing) and the `/assistant/checkout?package=<slug>` deep link its package CTAs target. One flag covers both halves of the funnel so they can never be enabled independently and strand a CTA. When off, the checkout deep link redirects to the in-app plans takeover.",
|
|
350
358
|
"defaultEnabled": false
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"id": "assistant-reply-push",
|
|
362
|
+
"scope": "assistant",
|
|
363
|
+
"key": "assistant-reply-push",
|
|
364
|
+
"label": "Assistant Reply Push",
|
|
365
|
+
"description": "Gates the `chat.assistant_reply` push notification the assistant sends at the end of a user-initiated turn whose reply the user has not seen. On by default; turn it off to silence the push without disabling the rest of the notification pipeline.",
|
|
366
|
+
"defaultEnabled": true
|
|
351
367
|
}
|
|
352
368
|
]
|
|
353
369
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "../providers/vellum-model-routing.js";
|
|
12
12
|
import { CALL_SITE_DEFAULTS } from "./call-site-defaults.js";
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
isDefaultProfileKey,
|
|
15
15
|
resolveDefaultProfileForProvider,
|
|
16
16
|
} from "./default-profile-catalog.js";
|
|
17
17
|
import {
|
|
@@ -114,12 +114,29 @@ export interface ResolveCallSiteOpts {
|
|
|
114
114
|
|
|
115
115
|
export type ResolutionFallbackReason = "missing" | "disabled" | "incomplete";
|
|
116
116
|
|
|
117
|
+
export interface ResolvedCallSiteConfig {
|
|
118
|
+
config: z.infer<typeof LLMConfigBase>;
|
|
119
|
+
profileName?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function resolveCallSiteConfigWithProfile(
|
|
123
|
+
callSite: LLMCallSite,
|
|
124
|
+
llm: z.infer<typeof LLMSchema>,
|
|
125
|
+
opts: ResolveCallSiteOpts = {},
|
|
126
|
+
): ResolvedCallSiteConfig {
|
|
127
|
+
const selection = selectWinningProfile(callSite, llm, opts);
|
|
128
|
+
return {
|
|
129
|
+
config: resolveOverrideOrDefault(callSite, llm, selection),
|
|
130
|
+
...(selection.profileName ? { profileName: selection.profileName } : {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
117
134
|
export function resolveCallSiteConfig(
|
|
118
135
|
callSite: LLMCallSite,
|
|
119
136
|
llm: z.infer<typeof LLMSchema>,
|
|
120
137
|
opts: ResolveCallSiteOpts = {},
|
|
121
138
|
): z.infer<typeof LLMConfigBase> {
|
|
122
|
-
return
|
|
139
|
+
return resolveCallSiteConfigWithProfile(callSite, llm, opts).config;
|
|
123
140
|
}
|
|
124
141
|
|
|
125
142
|
// ─── Single-winner profile resolution ───────────────────────────────────────
|
|
@@ -234,7 +251,7 @@ function providerAwareEntry(
|
|
|
234
251
|
name,
|
|
235
252
|
defaultProvider,
|
|
236
253
|
);
|
|
237
|
-
if (!
|
|
254
|
+
if (!isDefaultProfileKey(name) || entry?.mix != null) {
|
|
238
255
|
return entry;
|
|
239
256
|
}
|
|
240
257
|
if (
|
|
@@ -358,9 +375,8 @@ const CODE_DEFAULT_BASE: z.infer<typeof LLMConfigBase> = LLMConfigBase.parse(
|
|
|
358
375
|
function resolveOverrideOrDefault(
|
|
359
376
|
callSite: LLMCallSite,
|
|
360
377
|
llm: z.infer<typeof LLMSchema>,
|
|
361
|
-
|
|
378
|
+
selection: ProfileWinnerSelection,
|
|
362
379
|
): z.infer<typeof LLMConfigBase> {
|
|
363
|
-
const selection = selectWinningProfile(callSite, llm, opts);
|
|
364
380
|
const winnerFragment: Mergeable =
|
|
365
381
|
selection.entry == null ? {} : winnerConfigFragment(selection.entry);
|
|
366
382
|
|
package/src/config/loader.ts
CHANGED
|
@@ -1119,17 +1119,24 @@ export function loadConfig(): AssistantConfig {
|
|
|
1119
1119
|
// Drop the deployment-context embedding provider so it is never
|
|
1120
1120
|
// persisted (see above); the schema default re-applies in memory.
|
|
1121
1121
|
delete (seed.memory.embeddings as { provider?: unknown }).provider;
|
|
1122
|
-
//
|
|
1123
|
-
//
|
|
1124
|
-
//
|
|
1125
|
-
//
|
|
1126
|
-
//
|
|
1127
|
-
//
|
|
1128
|
-
//
|
|
1129
|
-
//
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1122
|
+
// Nothing under memory.v3 is persisted at seed time.
|
|
1123
|
+
//
|
|
1124
|
+
// The tuning knobs are globally-shipped defaults: freezing them to
|
|
1125
|
+
// disk would stop a shipped default change from reaching this
|
|
1126
|
+
// assistant (mirrors the embedding-provider strip above; migration 119
|
|
1127
|
+
// strips them from configs that already carry them).
|
|
1128
|
+
//
|
|
1129
|
+
// `live` stays absent because an absent leaf is the only way to
|
|
1130
|
+
// express "no decision recorded". This seed runs before workspace
|
|
1131
|
+
// migrations, and migration 105 defers to any value already present
|
|
1132
|
+
// (`if ("live" in v3Config) return`), unable to tell a deliberate
|
|
1133
|
+
// choice from a schema default. Writing the leaf here would pin a
|
|
1134
|
+
// brand-new workspace to the schema default; leaving it absent lets
|
|
1135
|
+
// 105 decide regardless of boot ordering. The schema default still
|
|
1136
|
+
// applies in memory on every load, and a hatch-time
|
|
1137
|
+
// `memory.v3.live=false` override still wins by merging after
|
|
1138
|
+
// migrations.
|
|
1139
|
+
seed.memory.v3 = {} as (typeof seed.memory)["v3"];
|
|
1133
1140
|
// Strip dataDir (runtime-derived) from the persisted config
|
|
1134
1141
|
const { dataDir: _, ...persistable } = seed;
|
|
1135
1142
|
writeFileSync(configPath, JSON.stringify(persistable, null, 2) + "\n");
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
DEFAULT_PROFILE_KEYS,
|
|
12
12
|
DEFAULT_PROFILE_PROVIDERS,
|
|
13
|
-
INTERNAL_PROFILE_KEYS,
|
|
14
13
|
} from "../default-profile-names.js";
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -714,18 +713,11 @@ export const LLMSchema = z
|
|
|
714
713
|
...Object.keys(config.profiles ?? {}),
|
|
715
714
|
...DEFAULT_PROFILE_KEYS,
|
|
716
715
|
]);
|
|
717
|
-
// Internal profiles exist only to be named by a call site, so they are
|
|
718
|
-
// valid reference targets there and nowhere else — never for
|
|
719
|
-
// `activeProfile`/`advisorProfile`, which are user-facing selections.
|
|
720
|
-
const callSiteProfileNames = new Set([
|
|
721
|
-
...profileNames,
|
|
722
|
-
...INTERNAL_PROFILE_KEYS,
|
|
723
|
-
]);
|
|
724
716
|
for (const [siteId, siteConfig] of Object.entries(config.callSites ?? {})) {
|
|
725
717
|
if (siteConfig?.profile == null) {
|
|
726
718
|
continue;
|
|
727
719
|
}
|
|
728
|
-
if (!
|
|
720
|
+
if (!profileNames.has(siteConfig.profile)) {
|
|
729
721
|
ctx.addIssue({
|
|
730
722
|
code: "custom",
|
|
731
723
|
path: ["callSites", siteId, "profile"],
|
|
@@ -39,6 +39,15 @@ export const MemoryRetrospectiveConfigSchema = z
|
|
|
39
39
|
"Minimum milliseconds between attempts (success or failure). Prevents tight retry loops across trigger types. Pre-compaction bypasses this gate.",
|
|
40
40
|
),
|
|
41
41
|
|
|
42
|
+
requireUserActivity: z
|
|
43
|
+
.boolean({
|
|
44
|
+
error: "memory.retrospective.requireUserActivity must be a boolean",
|
|
45
|
+
})
|
|
46
|
+
.default(true)
|
|
47
|
+
.describe(
|
|
48
|
+
"When true (default), a retrospective fires only when the unprocessed tail contains at least one user message carrying non-tool_result content. Tool results ride on user-role rows, so bare tool-result carriers do not count as user activity. Assistant-only stretches (proactive sends, broadcast recaps) are skipped with the cursor left in place, so the first retrospective after real user activity reviews the whole deferred stretch. Set false to run retrospectives over assistant-only activity as well.",
|
|
49
|
+
),
|
|
50
|
+
|
|
42
51
|
sweepIntervalMs: z
|
|
43
52
|
.number({
|
|
44
53
|
error: "memory.retrospective.sweepIntervalMs must be a number",
|
|
@@ -6,8 +6,9 @@ import { z } from "zod";
|
|
|
6
6
|
* The resource monitor runs as a separate OS process (a child of the assistant)
|
|
7
7
|
* that samples the container's own cgroup memory + workspace disk off the main
|
|
8
8
|
* event loop, so it keeps recording during a main-thread freeze and its samples
|
|
9
|
-
* survive an OOM SIGKILL.
|
|
10
|
-
*
|
|
9
|
+
* survive an OOM SIGKILL. On a slower timer it also compares each process's
|
|
10
|
+
* open file-descriptor count against its limit. The assistant spawns it at every
|
|
11
|
+
* startup: it is platform infrastructure, not an opt-in feature, and there is no
|
|
11
12
|
* config switch to turn it off. `assistant monitoring start`/`stop` control the
|
|
12
13
|
* process at runtime only; a stopped monitor respawns on the next boot.
|
|
13
14
|
*/
|
|
@@ -49,6 +50,31 @@ export const MonitoringConfigSchema = z
|
|
|
49
50
|
.describe(
|
|
50
51
|
"Minimum interval between high-memory snapshots, in milliseconds, so a sustained spike does not write a snapshot on every sample.",
|
|
51
52
|
),
|
|
53
|
+
fdPollIntervalMs: z
|
|
54
|
+
.number({ error: "monitoring.fdPollIntervalMs must be a number" })
|
|
55
|
+
.int("monitoring.fdPollIntervalMs must be an integer")
|
|
56
|
+
.min(1_000, "monitoring.fdPollIntervalMs must be at least 1000ms")
|
|
57
|
+
.max(1_800_000, "monitoring.fdPollIntervalMs must be <= 1800000ms")
|
|
58
|
+
.default(300_000)
|
|
59
|
+
.describe(
|
|
60
|
+
"How often the monitor walks the container's processes to compare their open file-descriptor counts against their limits, in milliseconds. Far slower than the memory sampler (default 5 minutes) because the walk costs a readdir per process and descriptor counts climb over minutes, not milliseconds.",
|
|
61
|
+
),
|
|
62
|
+
highFdThresholdRatio: z
|
|
63
|
+
.number({ error: "monitoring.highFdThresholdRatio must be a number" })
|
|
64
|
+
.min(0.1, "monitoring.highFdThresholdRatio must be >= 0.1")
|
|
65
|
+
.max(1, "monitoring.highFdThresholdRatio must be <= 1")
|
|
66
|
+
.default(0.8)
|
|
67
|
+
.describe(
|
|
68
|
+
"Fraction of a process's open-file soft limit (RLIMIT_NOFILE) at which the monitor logs a warning identifying the PIDs involved. Default 0.8, leaving headroom before open() starts failing with EMFILE.",
|
|
69
|
+
),
|
|
70
|
+
fdWarnCooldownMs: z
|
|
71
|
+
.number({ error: "monitoring.fdWarnCooldownMs must be a number" })
|
|
72
|
+
.int("monitoring.fdWarnCooldownMs must be an integer")
|
|
73
|
+
.min(0, "monitoring.fdWarnCooldownMs must be non-negative")
|
|
74
|
+
.default(60_000)
|
|
75
|
+
.describe(
|
|
76
|
+
"Minimum interval between file-descriptor warnings while usage stays over the threshold, in milliseconds. Crossing the threshold always warns immediately; this only throttles the repeats.",
|
|
77
|
+
),
|
|
52
78
|
pluginSourceScanIntervalMs: z
|
|
53
79
|
.number({
|
|
54
80
|
error: "monitoring.pluginSourceScanIntervalMs must be a number",
|
|
@@ -34,6 +34,21 @@ export const WorkspaceGitConfigSchema = z
|
|
|
34
34
|
.describe(
|
|
35
35
|
"Files larger than this (bytes) are excluded from workspace auto-commits",
|
|
36
36
|
),
|
|
37
|
+
historyCompaction: z
|
|
38
|
+
.object({
|
|
39
|
+
enabled: z
|
|
40
|
+
.boolean({
|
|
41
|
+
error: "workspaceGit.historyCompaction.enabled must be a boolean",
|
|
42
|
+
})
|
|
43
|
+
.default(true)
|
|
44
|
+
.describe(
|
|
45
|
+
"Whether background history compaction runs automatically. Manual compaction via the admin route is unaffected.",
|
|
46
|
+
),
|
|
47
|
+
})
|
|
48
|
+
.default({ enabled: true })
|
|
49
|
+
.describe(
|
|
50
|
+
"Background compaction of workspace git history (squashes commits older than the retention window to reclaim oversized blobs from .git)",
|
|
51
|
+
),
|
|
37
52
|
interactiveGitTimeoutMs: z
|
|
38
53
|
.number({
|
|
39
54
|
error: "workspaceGit.interactiveGitTimeoutMs must be a number",
|