@vellumai/assistant 0.8.11 → 0.8.12-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 +15 -17
- package/README.md +0 -6
- package/bun.lock +6 -122
- package/node_modules/@vellumai/gateway-client/bun.lock +1 -0
- package/node_modules/@vellumai/gateway-client/package.json +3 -1
- package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +1 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +87 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +3 -5
- package/openapi.yaml +633 -4
- package/package.json +1 -3
- package/src/__tests__/adaptive-thinking-repair.test.ts +185 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +7 -6
- package/src/__tests__/anthropic-provider.test.ts +129 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -1
- package/src/__tests__/btw-routes.test.ts +7 -34
- package/src/__tests__/checker.test.ts +6 -12
- package/src/__tests__/config-loader-backfill.test.ts +4 -2
- package/src/__tests__/config-loader-quarantine-notice.test.ts +167 -0
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-error.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +8 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/disk-pressure-tools.test.ts +1 -1
- package/src/__tests__/exploration-drift-hook.test.ts +692 -0
- package/src/__tests__/filing-service.test.ts +8 -3
- package/src/__tests__/guardian-action-store.test.ts +0 -167
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -1
- package/src/__tests__/heartbeat-service.test.ts +5 -2
- package/src/__tests__/identity-intro-cache.test.ts +12 -5
- package/src/__tests__/identity-routes.test.ts +16 -57
- package/src/__tests__/injector-chain.test.ts +8 -3
- package/src/__tests__/injector-config-quarantine-notice.test.ts +115 -0
- package/src/__tests__/llm-catalog-parity.test.ts +16 -0
- package/src/__tests__/llm-usage-store.test.ts +11 -0
- package/src/__tests__/log-export-workspace.test.ts +468 -3
- package/src/__tests__/memory-v2-static-injector.test.ts +22 -0
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +19 -8
- package/src/__tests__/openai-provider.test.ts +34 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +0 -1
- package/src/__tests__/recurrence-engine.test.ts +45 -0
- package/src/__tests__/schedule-routes.test.ts +34 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
- package/src/__tests__/script-proxy-conversation-manager.test.ts +10 -5
- package/src/__tests__/secret-fixtures.ts +20 -0
- package/src/__tests__/skill-tool-factory.test.ts +49 -0
- package/src/__tests__/subagent-role-registry.test.ts +24 -1
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/system-prompt.test.ts +109 -11
- package/src/__tests__/tool-approval-handler.test.ts +85 -0
- package/src/__tests__/tool-audit-listener.test.ts +86 -0
- package/src/__tests__/tool-error-hook.test.ts +1 -0
- package/src/__tests__/tool-result-spool.test.ts +337 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/validate-input.test.ts +95 -1
- package/src/__tests__/workspace-migration-098-remove-stale-updates-bulletin-file.test.ts +65 -0
- package/src/__tests__/workspace-migration-099-disable-cache-one-shot-callsites.test.ts +139 -0
- package/src/__tests__/workspace-migration-100-upgrade-quality-profile-to-fable-5.test.ts +174 -0
- package/src/__tests__/workspace-migration-101-upgrade-balanced-economy-to-minimax-m3.test.ts +162 -0
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +45 -95
- package/src/acp/__tests__/agent-process.test.ts +315 -2
- package/src/acp/__tests__/prepare-agent-env.test.ts +79 -5
- package/src/acp/agent-process.ts +163 -34
- package/src/acp/prepare-agent-env.ts +55 -15
- package/src/agent/loop.ts +81 -24
- package/src/api/events/usage-progress.ts +28 -0
- package/src/api/index.ts +6 -0
- package/src/background-wake/wake-intent-hooks.test.ts +2 -0
- package/src/bundler/app-bundler.ts +25 -42
- package/src/bundler/app-compiler.ts +8 -0
- package/src/calls/call-controller.ts +1 -1
- package/src/cli/commands/plugins.ts +248 -15
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +318 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +16 -9
- package/src/cli/lib/__tests__/plugin-artifact.test.ts +183 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +158 -0
- package/src/cli/lib/__tests__/plugin-fingerprint.test.ts +245 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +307 -0
- package/src/cli/lib/inspect-plugin.ts +252 -0
- package/src/cli/lib/install-from-github.ts +214 -21
- package/src/cli/lib/list-installed-plugins.ts +17 -6
- package/src/cli/lib/plugin-artifact.ts +103 -0
- package/src/cli/lib/plugin-details.ts +18 -1
- package/src/cli/lib/plugin-fingerprint.ts +197 -0
- package/src/cli/lib/upgrade-plugin.ts +225 -0
- package/src/config/bundled-skills/subagent/SKILL.md +2 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -2
- package/src/config/call-site-defaults.ts +13 -2
- package/src/config/feature-flag-registry.json +8 -16
- package/src/config/loader.ts +52 -59
- package/src/config/schema.ts +0 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +10 -0
- package/src/config/schemas/llm.ts +10 -0
- package/src/config/schemas/memory-v2.ts +13 -0
- package/src/config/schemas/memory-v3.ts +92 -0
- package/src/config/seed-inference-profiles.ts +4 -8
- package/src/context/post-turn-tool-result-truncation.ts +32 -18
- package/src/context/tool-result-spool.ts +104 -0
- package/src/credential-execution/feature-gates.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +41 -16
- package/src/daemon/conversation-error.ts +6 -15
- package/src/daemon/conversation.ts +9 -0
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/lifecycle.ts +1 -20
- package/src/daemon/message-types/conversations.ts +2 -15
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +40 -9
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -1
- package/src/home/__tests__/home-content-refresh.test.ts +114 -0
- package/src/home/__tests__/suggested-prompts.test.ts +86 -5
- package/src/home/home-content-refresh.ts +43 -31
- package/src/home/home-greeting-cache.ts +8 -1
- package/src/home/home-greeting.ts +13 -9
- package/src/home/suggested-prompts.ts +77 -24
- package/src/ipc/routes/trust-rules.test.ts +66 -72
- package/src/media/image-credentials.ts +2 -2
- package/src/memory/__tests__/compaction-log-store-clickhouse.test.ts +432 -0
- package/src/memory/{compaction-log-writer-clickhouse.ts → compaction-log-store-clickhouse.ts} +264 -55
- package/src/memory/conversation-attention-store.ts +1 -0
- package/src/memory/conversation-bootstrap.ts +18 -9
- package/src/memory/conversation-crud.ts +12 -2
- package/src/memory/conversation-title-service.ts +53 -9
- package/src/memory/delivery-channels.ts +0 -69
- package/src/memory/graph/extraction-job.ts +0 -15
- package/src/memory/guardian-action-store.ts +1 -376
- package/src/memory/llm-usage-store.ts +5 -1
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +2 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +183 -2
- package/src/memory/v2/__tests__/injection.test.ts +70 -0
- package/src/memory/v2/__tests__/static-context.test.ts +12 -0
- package/src/memory/v2/consolidation-job.ts +93 -9
- package/src/memory/v2/injection.ts +53 -0
- package/src/memory/v2/prompts/consolidation.ts +1 -0
- package/src/memory/v2/static-context.ts +13 -1
- package/src/memory/v2/sweep-job.ts +1 -1
- package/src/memory/v2/types.ts +5 -0
- package/src/plugin-api/types.ts +7 -0
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +300 -0
- package/src/plugins/defaults/exploration-drift/package.json +15 -0
- package/src/plugins/defaults/index.ts +25 -0
- package/src/plugins/defaults/memory-retrieval/injectors.ts +132 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/card.test.ts +92 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +2 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fresh-set.test.ts +52 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +2 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +136 -5
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +17 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +6 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +5 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +68 -4
- package/src/plugins/defaults/memory-v3-shadow/card.ts +49 -5
- package/src/plugins/defaults/memory-v3-shadow/fresh-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +4 -2
- package/src/plugins/defaults/memory-v3-shadow/learned-edges.test.ts +169 -0
- package/src/plugins/defaults/memory-v3-shadow/learned-edges.ts +178 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +115 -26
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +13 -9
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +144 -22
- package/src/plugins/defaults/memory-v3-shadow/types.ts +24 -6
- package/src/plugins/defaults/title-generate/hooks/stop.ts +13 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +16 -0
- package/src/prompts/cache-boundary.ts +17 -0
- package/src/prompts/sections.ts +50 -17
- package/src/prompts/system-prompt.ts +12 -4
- package/src/prompts/templates/system-sections.ts +22 -0
- package/src/providers/__tests__/unparseable-tool-args.test.ts +53 -0
- package/src/providers/anthropic/client.ts +74 -28
- package/src/providers/gemini/client.ts +5 -1
- package/src/providers/minimax/client.ts +9 -0
- package/src/providers/model-catalog.ts +28 -0
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/chat-completions-provider.ts +4 -2
- package/src/providers/openai/responses-provider.ts +7 -2
- package/src/providers/retry.ts +8 -0
- package/src/providers/types.ts +11 -0
- package/src/providers/unparseable-tool-args.ts +56 -0
- package/src/runtime/AGENTS.md +6 -0
- package/src/runtime/__tests__/agent-wake.test.ts +2 -2
- package/src/runtime/agent-wake.ts +5 -5
- package/src/runtime/background-job-runner.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +150 -3
- package/src/runtime/migrations/vbundle-import-analyzer.ts +29 -6
- package/src/runtime/migrations/vbundle-import-policy.ts +23 -0
- package/src/runtime/migrations/vbundle-importer.ts +9 -4
- package/src/runtime/migrations/vbundle-streaming-importer.ts +8 -3
- package/src/runtime/pre-first-message-gate.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +241 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +132 -0
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +97 -185
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +17 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +348 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +3 -3
- package/src/runtime/routes/btw-routes.ts +0 -14
- package/src/runtime/routes/conversation-compaction-routes.ts +86 -19
- package/src/runtime/routes/conversation-list-routes.ts +77 -5
- package/src/runtime/routes/conversation-management-routes.ts +54 -0
- package/src/runtime/routes/conversation-query-routes.ts +79 -4
- package/src/runtime/routes/gateway-log-routes.ts +14 -64
- package/src/runtime/routes/home-feed-routes.ts +10 -0
- package/src/runtime/routes/identity-intro-cache.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +76 -20
- package/src/runtime/routes/inbound-message-handler.ts +0 -36
- package/src/runtime/routes/log-export-routes.ts +143 -96
- package/src/runtime/routes/plugins-routes.ts +380 -0
- package/src/runtime/routes/redact-staged-export.ts +259 -0
- package/src/runtime/routes/schedule-routes.ts +19 -2
- package/src/runtime/routes/trust-rules-routes.ts +14 -67
- package/src/schedule/recurrence-engine.ts +34 -0
- package/src/schedule/scheduler.ts +1 -0
- package/src/security/redact-json.ts +61 -0
- package/src/skills/validate-input.ts +41 -1
- package/src/subagent/types.ts +26 -1
- package/src/telemetry/types.ts +15 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +6 -1
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/apps/executors.ts +1 -1
- package/src/tools/skills/skill-tool-factory.ts +19 -8
- package/src/tools/tool-approval-handler.ts +31 -0
- package/src/usage/types.ts +8 -1
- package/src/util/platform.ts +16 -0
- package/src/watcher/engine.ts +1 -0
- package/src/workspace/adaptive-thinking-repair.ts +113 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +70 -67
- package/src/workspace/migrations/098-remove-stale-updates-bulletin-file.ts +31 -0
- package/src/workspace/migrations/099-disable-cache-one-shot-callsites.ts +81 -0
- package/src/workspace/migrations/100-upgrade-quality-profile-to-fable-5.ts +86 -0
- package/src/workspace/migrations/101-upgrade-balanced-economy-to-minimax-m3.ts +70 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +0 -202
- package/src/__tests__/conversation-starters-cadence.test.ts +0 -161
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -322
- package/src/__tests__/guardian-action-followup-store.test.ts +0 -373
- package/src/__tests__/guardian-action-late-reply.test.ts +0 -1083
- package/src/__tests__/update-bulletin-job.test.ts +0 -292
- package/src/config/schemas/updates.ts +0 -14
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +0 -227
- package/src/memory/conversation-starters-cadence.ts +0 -78
- package/src/prompts/update-bulletin-job.ts +0 -180
- package/src/runtime/guardian-action-followup-executor.ts +0 -306
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
// Enable adaptive thinking on the managed "balanced" and "quality-optimized"
|
|
5
|
+
// profiles.
|
|
6
|
+
//
|
|
7
|
+
// The assistant-side seed defaults (MANAGED_PROFILE_TEMPLATES in
|
|
8
|
+
// seed-inference-profiles.ts) already ship thinking: { enabled: true,
|
|
9
|
+
// streamThinking: true } for both profiles, which normalizes to
|
|
10
|
+
// { type: "adaptive" } on the wire. Off-platform (BYOK) instances pick this
|
|
11
|
+
// up on every boot because the seeder overwrites managed profiles. On-platform
|
|
12
|
+
// instances preserve existing profiles (the platform overlay is authoritative),
|
|
13
|
+
// so instances that were hatched before thinking was enabled in the templates
|
|
14
|
+
// are stuck with thinking disabled or absent.
|
|
15
|
+
//
|
|
16
|
+
// Workspace migration 097 patches the on-disk config once, but it runs before
|
|
17
|
+
// mergeDefaultWorkspaceConfig() which can overwrite the fix with overlay
|
|
18
|
+
// profiles that have thinking disabled or absent. lifecycle.ts calls this
|
|
19
|
+
// repair again after the overlay merge + profile seeding so the fix sticks.
|
|
20
|
+
// The migration keeps its own frozen copy of this logic (migration files are
|
|
21
|
+
// self-contained snapshots and must not be imported from).
|
|
22
|
+
//
|
|
23
|
+
// The repair patches both profiles, adding thinking: { enabled: true,
|
|
24
|
+
// streamThinking: true } where it's missing or explicitly disabled. It skips
|
|
25
|
+
// profiles that:
|
|
26
|
+
// - Don't exist (no profile to patch)
|
|
27
|
+
// - Already have thinking enabled (idempotent)
|
|
28
|
+
// - Are source: "user" (user-created profiles are untouched)
|
|
29
|
+
// - Have a non-managed, non-absent source (unknown origin)
|
|
30
|
+
// - Resolve to a non-Anthropic provider (adaptive thinking is
|
|
31
|
+
// Anthropic-specific). A profile with no explicit provider inherits
|
|
32
|
+
// llm.default.provider, so the check falls back to that — with a
|
|
33
|
+
// completely absent llm.default.provider treated as Anthropic, matching
|
|
34
|
+
// migration 052's own `?? "anthropic"` default. This keeps the legacy
|
|
35
|
+
// non-Anthropic empty `{}` shells seeded by migration 052 off the repair.
|
|
36
|
+
|
|
37
|
+
const ADAPTIVE_THINKING = { enabled: true, streamThinking: true } as const;
|
|
38
|
+
const TARGET_PROFILES = ["balanced", "quality-optimized"] as const;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Patch managed Anthropic profiles that are missing adaptive thinking.
|
|
42
|
+
*
|
|
43
|
+
* Idempotent: profiles that already have thinking enabled are skipped.
|
|
44
|
+
*/
|
|
45
|
+
export function repairAdaptiveThinkingOnManagedProfiles(
|
|
46
|
+
workspaceDir: string,
|
|
47
|
+
): void {
|
|
48
|
+
const configPath = join(workspaceDir, "config.json");
|
|
49
|
+
if (!existsSync(configPath)) return;
|
|
50
|
+
|
|
51
|
+
let config: Record<string, unknown>;
|
|
52
|
+
try {
|
|
53
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
54
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
55
|
+
config = raw as Record<string, unknown>;
|
|
56
|
+
} catch {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const llm = readObject(config.llm);
|
|
61
|
+
if (llm === null) return;
|
|
62
|
+
|
|
63
|
+
const profiles = readObject(llm.profiles);
|
|
64
|
+
if (profiles === null) return;
|
|
65
|
+
|
|
66
|
+
// Profiles without an explicit provider inherit llm.default.provider at
|
|
67
|
+
// resolution time; an absent llm.default.provider resolves to Anthropic.
|
|
68
|
+
const defaultBlock = readObject(llm.default);
|
|
69
|
+
const defaultProvider =
|
|
70
|
+
typeof defaultBlock?.provider === "string"
|
|
71
|
+
? defaultBlock.provider
|
|
72
|
+
: "anthropic";
|
|
73
|
+
|
|
74
|
+
let changed = false;
|
|
75
|
+
|
|
76
|
+
for (const name of TARGET_PROFILES) {
|
|
77
|
+
const profile = readObject(profiles[name]);
|
|
78
|
+
if (profile === null) continue;
|
|
79
|
+
|
|
80
|
+
// Only patch managed Anthropic profiles.
|
|
81
|
+
// Legacy profiles created before the `source` metadata field was introduced
|
|
82
|
+
// have source=undefined. Treat these as managed when the profile name is one
|
|
83
|
+
// of the canonical managed names (which TARGET_PROFILES already guarantees)
|
|
84
|
+
// and the effective provider — explicit, or inherited from llm.default — is
|
|
85
|
+
// Anthropic. Explicit `source: "user"` profiles are always skipped.
|
|
86
|
+
if (profile.source === "user") continue;
|
|
87
|
+
if (profile.source !== undefined && profile.source !== "managed") continue;
|
|
88
|
+
const effectiveProvider =
|
|
89
|
+
typeof profile.provider === "string" ? profile.provider : defaultProvider;
|
|
90
|
+
if (effectiveProvider !== "anthropic") continue;
|
|
91
|
+
|
|
92
|
+
// Skip if thinking is already enabled.
|
|
93
|
+
const thinking = readObject(profile.thinking);
|
|
94
|
+
if (thinking !== null && thinking.enabled === true) continue;
|
|
95
|
+
|
|
96
|
+
profile.thinking = { ...ADAPTIVE_THINKING };
|
|
97
|
+
profiles[name] = profile;
|
|
98
|
+
changed = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (changed) {
|
|
102
|
+
llm.profiles = profiles;
|
|
103
|
+
config.llm = llm;
|
|
104
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
109
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return value as Record<string, unknown>;
|
|
113
|
+
}
|
|
@@ -22,87 +22,90 @@ import type { WorkspaceMigration } from "./types.js";
|
|
|
22
22
|
// - Already have thinking enabled (idempotent)
|
|
23
23
|
// - Are source: "user" (user-created profiles are untouched)
|
|
24
24
|
// - Have a non-managed, non-absent source (unknown origin)
|
|
25
|
-
// -
|
|
25
|
+
// - Resolve to a non-Anthropic provider (adaptive thinking is
|
|
26
|
+
// Anthropic-specific). A profile with no explicit provider inherits
|
|
27
|
+
// llm.default.provider, so the check falls back to that — with a
|
|
28
|
+
// completely absent llm.default.provider treated as Anthropic, matching
|
|
29
|
+
// migration 052's own `?? "anthropic"` default. This keeps the legacy
|
|
30
|
+
// non-Anthropic empty `{}` shells seeded by migration 052 off the repair.
|
|
31
|
+
//
|
|
32
|
+
// Note: the live startup path re-runs the same repair after the platform
|
|
33
|
+
// overlay merge — see assistant/src/workspace/adaptive-thinking-repair.ts.
|
|
34
|
+
// This file keeps its own frozen copy of the logic because migration modules
|
|
35
|
+
// are self-contained snapshots and must never be imported by other code.
|
|
26
36
|
|
|
27
37
|
const ADAPTIVE_THINKING = { enabled: true, streamThinking: true } as const;
|
|
28
38
|
const TARGET_PROFILES = ["balanced", "quality-optimized"] as const;
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
* The function is idempotent: profiles that already have thinking enabled are skipped.
|
|
40
|
-
*/
|
|
41
|
-
export function repairAdaptiveThinkingOnManagedProfiles(
|
|
42
|
-
workspaceDir: string,
|
|
43
|
-
): void {
|
|
44
|
-
const configPath = join(workspaceDir, "config.json");
|
|
45
|
-
if (!existsSync(configPath)) return;
|
|
40
|
+
export const enableAdaptiveThinkingManagedProfilesMigration: WorkspaceMigration =
|
|
41
|
+
{
|
|
42
|
+
id: "097-enable-adaptive-thinking-managed-profiles",
|
|
43
|
+
description:
|
|
44
|
+
"Enable adaptive thinking on managed balanced and quality-optimized profiles",
|
|
45
|
+
run(workspaceDir: string): void {
|
|
46
|
+
const configPath = join(workspaceDir, "config.json");
|
|
47
|
+
if (!existsSync(configPath)) return;
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
let config: Record<string, unknown>;
|
|
50
|
+
try {
|
|
51
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
52
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
53
|
+
config = raw as Record<string, unknown>;
|
|
54
|
+
} catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const llm = readObject(config.llm);
|
|
59
|
+
if (llm === null) return;
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
const profiles = readObject(llm.profiles);
|
|
62
|
+
if (profiles === null) return;
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
// Profiles without an explicit provider inherit llm.default.provider at
|
|
65
|
+
// resolution time; an absent llm.default.provider resolves to Anthropic.
|
|
66
|
+
const defaultBlock = readObject(llm.default);
|
|
67
|
+
const defaultProvider =
|
|
68
|
+
typeof defaultBlock?.provider === "string"
|
|
69
|
+
? defaultBlock.provider
|
|
70
|
+
: "anthropic";
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
const profile = readObject(profiles[name]);
|
|
66
|
-
if (profile === null) continue;
|
|
72
|
+
let changed = false;
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// of the canonical managed names (which TARGET_PROFILES already guarantees)
|
|
72
|
-
// and the provider is Anthropic (or absent). Explicit `source: "user"`
|
|
73
|
-
// profiles are always skipped.
|
|
74
|
-
if (profile.source === "user") continue;
|
|
75
|
-
if (profile.source !== undefined && profile.source !== "managed") continue;
|
|
76
|
-
if (
|
|
77
|
-
typeof profile.provider === "string" &&
|
|
78
|
-
profile.provider !== "anthropic"
|
|
79
|
-
) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
74
|
+
for (const name of TARGET_PROFILES) {
|
|
75
|
+
const profile = readObject(profiles[name]);
|
|
76
|
+
if (profile === null) continue;
|
|
82
77
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
// Only patch managed Anthropic profiles.
|
|
79
|
+
// Legacy profiles created before the `source` metadata field was
|
|
80
|
+
// introduced have source=undefined. Treat these as managed when the
|
|
81
|
+
// profile name is one of the canonical managed names (which
|
|
82
|
+
// TARGET_PROFILES already guarantees) and the effective provider —
|
|
83
|
+
// explicit, or inherited from llm.default — is Anthropic. Explicit
|
|
84
|
+
// `source: "user"` profiles are always skipped.
|
|
85
|
+
if (profile.source === "user") continue;
|
|
86
|
+
if (profile.source !== undefined && profile.source !== "managed") {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const effectiveProvider =
|
|
90
|
+
typeof profile.provider === "string"
|
|
91
|
+
? profile.provider
|
|
92
|
+
: defaultProvider;
|
|
93
|
+
if (effectiveProvider !== "anthropic") continue;
|
|
86
94
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
95
|
+
// Skip if thinking is already enabled.
|
|
96
|
+
const thinking = readObject(profile.thinking);
|
|
97
|
+
if (thinking !== null && thinking.enabled === true) continue;
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
}
|
|
99
|
+
profile.thinking = { ...ADAPTIVE_THINKING };
|
|
100
|
+
profiles[name] = profile;
|
|
101
|
+
changed = true;
|
|
102
|
+
}
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
run(workspaceDir: string): void {
|
|
105
|
-
repairAdaptiveThinkingOnManagedProfiles(workspaceDir);
|
|
104
|
+
if (changed) {
|
|
105
|
+
llm.profiles = profiles;
|
|
106
|
+
config.llm = llm;
|
|
107
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
108
|
+
}
|
|
106
109
|
},
|
|
107
110
|
down(_workspaceDir: string): void {
|
|
108
111
|
// Forward-only.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { rmSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
const MIGRATION_ID = "098-remove-stale-updates-bulletin-file";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Delete `<workspace>/UPDATES.md`.
|
|
10
|
+
*
|
|
11
|
+
* Release notes used to be appended to the file by workspace migrations and
|
|
12
|
+
* processed by a background conversation dispatched at daemon startup. That
|
|
13
|
+
* feature has been removed — nothing consumes the file's contents anymore,
|
|
14
|
+
* and it was system-written bulletin material, so it is deleted outright.
|
|
15
|
+
*
|
|
16
|
+
* Idempotent: `rmSync` with `force` is a no-op when the file is absent.
|
|
17
|
+
*/
|
|
18
|
+
export const removeStaleUpdatesBulletinFileMigration: WorkspaceMigration = {
|
|
19
|
+
id: MIGRATION_ID,
|
|
20
|
+
description:
|
|
21
|
+
"Delete leftover UPDATES.md release-note bulletins (processing job removed)",
|
|
22
|
+
|
|
23
|
+
run(workspaceDir: string): void {
|
|
24
|
+
rmSync(join(workspaceDir, "UPDATES.md"), { force: true });
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
down(_workspaceDir: string): void {
|
|
28
|
+
// Forward-only: the removed content was pending release-note bulletins
|
|
29
|
+
// for a feature that no longer exists.
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Add `disableCache: true` to existing on-disk entries for the one-shot LLM
|
|
8
|
+
* call sites whose shipped defaults now opt out of prompt caching.
|
|
9
|
+
*
|
|
10
|
+
* The resolver prefers an explicit `llm.callSites.<id>` entry over
|
|
11
|
+
* CALL_SITE_DEFAULTS, and earlier migrations (054 recall, 072 replySuggestion,
|
|
12
|
+
* and platform overlays for the others) seeded such entries. Without this
|
|
13
|
+
* migration, upgraded workspaces would keep paying prompt-cache writes on
|
|
14
|
+
* call sites whose prompts never produce a cache read — only fresh installs
|
|
15
|
+
* would pick up the new shipped default.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent and customization-preserving: an entry that already carries a
|
|
18
|
+
* `disableCache` key (either value — the user may have opted back in) is
|
|
19
|
+
* left untouched, and only the one key is added to entries we patch. Entries
|
|
20
|
+
* that don't exist on disk are skipped — those workspaces already resolve
|
|
21
|
+
* the shipped default.
|
|
22
|
+
*/
|
|
23
|
+
const ONE_SHOT_CALL_SITES = [
|
|
24
|
+
"recall",
|
|
25
|
+
"replySuggestion",
|
|
26
|
+
"homeGreeting",
|
|
27
|
+
"homeSuggestedPrompts",
|
|
28
|
+
"conversationTitle",
|
|
29
|
+
"memoryConsolidation",
|
|
30
|
+
] as const;
|
|
31
|
+
|
|
32
|
+
export const disableCacheOneShotCallsitesMigration: WorkspaceMigration = {
|
|
33
|
+
id: "099-disable-cache-one-shot-callsites",
|
|
34
|
+
description:
|
|
35
|
+
"Add disableCache: true to existing one-shot call-site entries so upgraded workspaces match the new shipped defaults",
|
|
36
|
+
run(workspaceDir: string): void {
|
|
37
|
+
if (process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH) return;
|
|
38
|
+
|
|
39
|
+
const configPath = join(workspaceDir, "config.json");
|
|
40
|
+
if (!existsSync(configPath)) return;
|
|
41
|
+
|
|
42
|
+
let config: Record<string, unknown> = {};
|
|
43
|
+
try {
|
|
44
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
45
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
46
|
+
config = raw as Record<string, unknown>;
|
|
47
|
+
} catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const llm = readObject(config.llm);
|
|
52
|
+
if (llm === null) return;
|
|
53
|
+
const callSites = readObject(llm.callSites);
|
|
54
|
+
if (callSites === null) return;
|
|
55
|
+
|
|
56
|
+
let changed = false;
|
|
57
|
+
for (const callSite of ONE_SHOT_CALL_SITES) {
|
|
58
|
+
const entry = readObject(callSites[callSite]);
|
|
59
|
+
if (entry === null) continue;
|
|
60
|
+
if ("disableCache" in entry) continue;
|
|
61
|
+
entry.disableCache = true;
|
|
62
|
+
callSites[callSite] = entry;
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
if (!changed) return;
|
|
66
|
+
|
|
67
|
+
llm.callSites = callSites;
|
|
68
|
+
config.llm = llm;
|
|
69
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
70
|
+
},
|
|
71
|
+
down(_workspaceDir: string): void {
|
|
72
|
+
// Forward-only.
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
77
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return value as Record<string, unknown>;
|
|
81
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Upgrade quality-optimized profiles to Claude Fable 5.
|
|
7
|
+
//
|
|
8
|
+
// The quality-optimized model intent moved to claude-fable-5 (#34498), but
|
|
9
|
+
// the intent map is only consulted when a profile is seeded: off-platform
|
|
10
|
+
// installs reseed managed profiles on every boot, while on-platform
|
|
11
|
+
// workspaces keep the profile they were hatched with — the seeder skips
|
|
12
|
+
// existing profiles there, and the hatch overlay is consumed exactly once.
|
|
13
|
+
// Existing platform assistants are therefore stuck on whichever model the
|
|
14
|
+
// quality intent pointed at when they hatched (claude-opus-4-7 or
|
|
15
|
+
// claude-opus-4-8) until a migration rewrites it.
|
|
16
|
+
//
|
|
17
|
+
// Only the managed quality-optimized profile is touched — the user-owned
|
|
18
|
+
// custom-quality-optimized copy is theirs to manage. Within it, only a model
|
|
19
|
+
// still on a previous quality-intent default is upgraded — matching by model
|
|
20
|
+
// value also covers the OpenRouter-prefixed ids. A profile whose model the
|
|
21
|
+
// user changed to anything else is left untouched.
|
|
22
|
+
|
|
23
|
+
const TARGET_PROFILES = ["quality-optimized"];
|
|
24
|
+
|
|
25
|
+
const MODEL_UPGRADES: Record<string, string> = {
|
|
26
|
+
"claude-opus-4-7": "claude-fable-5",
|
|
27
|
+
"claude-opus-4-8": "claude-fable-5",
|
|
28
|
+
"anthropic/claude-opus-4.7": "anthropic/claude-fable-5",
|
|
29
|
+
"anthropic/claude-opus-4.8": "anthropic/claude-fable-5",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const upgradeQualityProfileToFable5Migration: WorkspaceMigration = {
|
|
33
|
+
id: "100-upgrade-quality-profile-to-fable-5",
|
|
34
|
+
description:
|
|
35
|
+
"Upgrade the managed quality-optimized profile from Opus 4.7/4.8 to Claude Fable 5",
|
|
36
|
+
run(workspaceDir: string): void {
|
|
37
|
+
const configPath = join(workspaceDir, "config.json");
|
|
38
|
+
if (!existsSync(configPath)) return;
|
|
39
|
+
|
|
40
|
+
let config: Record<string, unknown>;
|
|
41
|
+
try {
|
|
42
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
43
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
44
|
+
config = raw as Record<string, unknown>;
|
|
45
|
+
} catch {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const llm = readObject(config.llm);
|
|
50
|
+
if (llm === null) return;
|
|
51
|
+
|
|
52
|
+
const profiles = readObject(llm.profiles);
|
|
53
|
+
if (profiles === null) return;
|
|
54
|
+
|
|
55
|
+
let changed = false;
|
|
56
|
+
|
|
57
|
+
for (const name of TARGET_PROFILES) {
|
|
58
|
+
const profile = readObject(profiles[name]);
|
|
59
|
+
if (profile === null) continue;
|
|
60
|
+
if (typeof profile.model !== "string") continue;
|
|
61
|
+
|
|
62
|
+
const upgraded = MODEL_UPGRADES[profile.model];
|
|
63
|
+
if (upgraded === undefined) continue;
|
|
64
|
+
|
|
65
|
+
profile.model = upgraded;
|
|
66
|
+
profiles[name] = profile;
|
|
67
|
+
changed = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (changed) {
|
|
71
|
+
llm.profiles = profiles;
|
|
72
|
+
config.llm = llm;
|
|
73
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
down(_workspaceDir: string): void {
|
|
77
|
+
// Forward-only.
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
82
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return value as Record<string, unknown>;
|
|
86
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
// Switch the Balanced Economy profile from Kimi K2.6 to MiniMax M3.
|
|
7
|
+
//
|
|
8
|
+
// The Fireworks balanced model intent moved to MiniMax M3 (#34726), but the
|
|
9
|
+
// intent map is only consulted when a profile is seeded: off-platform
|
|
10
|
+
// installs reseed managed profiles on every boot, while on-platform
|
|
11
|
+
// workspaces keep the profile they were hatched with — the seeder skips
|
|
12
|
+
// existing profiles there. Existing platform assistants would otherwise stay
|
|
13
|
+
// on Kimi K2.6 (including the now-dropped `suppress-cjk` logit-bias preset)
|
|
14
|
+
// until a migration rewrites the profile.
|
|
15
|
+
//
|
|
16
|
+
// Only the managed balanced-economy profile still pointing at the old
|
|
17
|
+
// default model is touched — a profile whose model the user changed is left
|
|
18
|
+
// alone. The rewrite mirrors the new seed template: MiniMax M3, 32K max
|
|
19
|
+
// output tokens, no logit-bias preset.
|
|
20
|
+
|
|
21
|
+
const OLD_MODEL = "accounts/fireworks/models/kimi-k2p6";
|
|
22
|
+
const NEW_MODEL = "accounts/fireworks/models/minimax-m3";
|
|
23
|
+
|
|
24
|
+
export const upgradeBalancedEconomyToMinimaxM3Migration: WorkspaceMigration = {
|
|
25
|
+
id: "101-upgrade-balanced-economy-to-minimax-m3",
|
|
26
|
+
description:
|
|
27
|
+
"Switch the managed Balanced Economy profile from Kimi K2.6 to MiniMax M3",
|
|
28
|
+
run(workspaceDir: string): void {
|
|
29
|
+
const configPath = join(workspaceDir, "config.json");
|
|
30
|
+
if (!existsSync(configPath)) return;
|
|
31
|
+
|
|
32
|
+
let config: Record<string, unknown>;
|
|
33
|
+
try {
|
|
34
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
35
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
36
|
+
config = raw as Record<string, unknown>;
|
|
37
|
+
} catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const llm = readObject(config.llm);
|
|
42
|
+
if (llm === null) return;
|
|
43
|
+
|
|
44
|
+
const profiles = readObject(llm.profiles);
|
|
45
|
+
if (profiles === null) return;
|
|
46
|
+
|
|
47
|
+
const profile = readObject(profiles["balanced-economy"]);
|
|
48
|
+
if (profile === null || profile.model !== OLD_MODEL) return;
|
|
49
|
+
|
|
50
|
+
profile.model = NEW_MODEL;
|
|
51
|
+
profile.description =
|
|
52
|
+
"Strong open model (MiniMax M3) at a lower price point";
|
|
53
|
+
profile.maxTokens = 32000;
|
|
54
|
+
delete profile.logitBias;
|
|
55
|
+
profiles["balanced-economy"] = profile;
|
|
56
|
+
llm.profiles = profiles;
|
|
57
|
+
config.llm = llm;
|
|
58
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
59
|
+
},
|
|
60
|
+
down(_workspaceDir: string): void {
|
|
61
|
+
// Forward-only.
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
66
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return value as Record<string, unknown>;
|
|
70
|
+
}
|
|
@@ -95,6 +95,10 @@ import { seedAvatarManifestMigration } from "./094-seed-avatar-manifest.js";
|
|
|
95
95
|
import { bumpHeartbeatInterval30mTo60mMigration } from "./095-bump-heartbeat-interval-30m-to-60m.js";
|
|
96
96
|
import { reduceQualityProfileEffortMigration } from "./096-reduce-quality-profile-effort.js";
|
|
97
97
|
import { enableAdaptiveThinkingManagedProfilesMigration } from "./097-enable-adaptive-thinking-managed-profiles.js";
|
|
98
|
+
import { removeStaleUpdatesBulletinFileMigration } from "./098-remove-stale-updates-bulletin-file.js";
|
|
99
|
+
import { disableCacheOneShotCallsitesMigration } from "./099-disable-cache-one-shot-callsites.js";
|
|
100
|
+
import { upgradeQualityProfileToFable5Migration } from "./100-upgrade-quality-profile-to-fable-5.js";
|
|
101
|
+
import { upgradeBalancedEconomyToMinimaxM3Migration } from "./101-upgrade-balanced-economy-to-minimax-m3.js";
|
|
98
102
|
import { migrateToWorkspaceVolumeMigration } from "./migrate-to-workspace-volume.js";
|
|
99
103
|
import type { WorkspaceMigration } from "./types.js";
|
|
100
104
|
|
|
@@ -201,4 +205,8 @@ export const WORKSPACE_MIGRATIONS: WorkspaceMigration[] = [
|
|
|
201
205
|
bumpHeartbeatInterval30mTo60mMigration,
|
|
202
206
|
reduceQualityProfileEffortMigration,
|
|
203
207
|
enableAdaptiveThinkingManagedProfilesMigration,
|
|
208
|
+
removeStaleUpdatesBulletinFileMigration,
|
|
209
|
+
disableCacheOneShotCallsitesMigration,
|
|
210
|
+
upgradeQualityProfileToFable5Migration,
|
|
211
|
+
upgradeBalancedEconomyToMinimaxM3Migration,
|
|
204
212
|
];
|