ui: align persisted config with strict server schema and enable thinking by default (#25242)

* ui: migrate legacy string-encoded booleans in persisted config

* ui: enable thinking by default

Fresh users and legacy conversations without a persisted thinking
preference now default to enabled. The per-conversation toggle and
the persisted localStorage choice keep taking precedence.

Picks up the enable_thinking default from #24876.
This commit is contained in:
Pascal
2026-07-03 13:14:52 +02:00
committed by GitHub
parent b5315e16e0
commit 067de93718
2 changed files with 42 additions and 7 deletions
+37 -1
View File
@@ -551,13 +551,49 @@ const mcpDefaultEnabledMigration: Migration = {
} }
}; };
const CONFIG_TYPES_MIGRATION_ID = 'config-type-normalization-v1';
const configTypesMigration: Migration = {
id: CONFIG_TYPES_MIGRATION_ID,
description: 'Coerce legacy string-encoded booleans in persisted config to real booleans',
async run(): Promise<void> {
const configRaw = localStorage.getItem(CONFIG_LOCALSTORAGE_KEY);
if (configRaw === null) return;
const config = JSON.parse(configRaw);
let changed = false;
// Pre-schema configs persisted booleans as the strings "true"/"false", which the
// strict server schema now rejects. Coerce those back to real booleans. No config
// string field holds exactly "true"/"false", so the match is unambiguous.
for (const key of Object.keys(config)) {
if (config[key] === 'true') {
config[key] = true;
changed = true;
} else if (config[key] === 'false') {
config[key] = false;
changed = true;
}
}
if (changed) {
localStorage.setItem(CONFIG_LOCALSTORAGE_KEY, JSON.stringify(config));
}
if (import.meta.env.DEV && import.meta.env.VITE_DEBUG)
console.log(`[Migration] Config types: coerced string booleans (changed=${changed})`);
}
};
const migrations: Migration[] = [ const migrations: Migration[] = [
localStorageMigration, localStorageMigration,
idxdbMigration, idxdbMigration,
legacyMessageMigration, legacyMessageMigration,
themeMigration, themeMigration,
customJsonKeyMigration, customJsonKeyMigration,
mcpDefaultEnabledMigration mcpDefaultEnabledMigration,
configTypesMigration
]; ];
export const MigrationService = { export const MigrationService = {
@@ -114,14 +114,13 @@ class ConversationsStore {
/** Load thinking-enabled default from localStorage */ /** Load thinking-enabled default from localStorage */
private static loadThinkingDefaults(): boolean { private static loadThinkingDefaults(): boolean {
if (typeof globalThis.localStorage === 'undefined') return false; if (typeof globalThis.localStorage === 'undefined') return true;
try { try {
const raw = localStorage.getItem(THINKING_ENABLED_DEFAULT_LOCALSTORAGE_KEY); const raw = localStorage.getItem(THINKING_ENABLED_DEFAULT_LOCALSTORAGE_KEY);
if (!raw) return false; if (!raw) return true;
const parsed = raw === 'true'; return raw === 'true';
return typeof parsed === 'boolean' ? parsed : false;
} catch { } catch {
return false; return true;
} }
} }
@@ -333,7 +332,7 @@ class ConversationsStore {
} }
this.pendingMcpServerOverrides = []; this.pendingMcpServerOverrides = [];
this.pendingThinkingEnabled = false; this.pendingThinkingEnabled = ConversationsStore.loadThinkingDefaults();
this.activeConversation = conversation; this.activeConversation = conversation;
if (conversation.currNode) { if (conversation.currNode) {