fix(#5435): stop startup workspace repair from persisting speech defaults

This commit is contained in:
Rod Boev committed 2026-07-02 21:28:46 -04:00
1 parent 8f7b9c1d0d
commit fdacb4b922
2 files changed
+57 -12

No files matched your search

+23 -12
View File
@@ -8194,6 +8194,18 @@ def persisted_speech_settings_keys() -> list[str]:
return sorted(_extract_persisted_speech_keys(_read_raw_settings_file())) return sorted(_extract_persisted_speech_keys(_read_raw_settings_file()))
def _settings_payload_for_write(settings: dict, persisted_speech_keys: set[str]) -> dict:
persisted = {
k: v
for k, v in settings.items()
if k not in {"default_model", _SETTINGS_PERSISTED_SPEECH_KEYS_FIELD}
}
for speech_key in _SETTINGS_SPEECH_KEYS:
if speech_key not in persisted_speech_keys:
persisted.pop(speech_key, None)
return persisted
def load_settings() -> dict: def load_settings() -> dict:
"""Load settings from disk, merging with defaults for any missing keys.""" """Load settings from disk, merging with defaults for any missing keys."""
settings = dict(_SETTINGS_DEFAULTS) settings = dict(_SETTINGS_DEFAULTS)
@@ -8515,17 +8527,7 @@ def save_settings(settings: dict) -> dict:
) )
effective_persisted_speech_keys = set(persisted_speech_keys) effective_persisted_speech_keys = set(persisted_speech_keys)
effective_persisted_speech_keys.update(applied_speech_keys) effective_persisted_speech_keys.update(applied_speech_keys)
persisted = { persisted = _settings_payload_for_write(current, effective_persisted_speech_keys)
k: v
for k, v in current.items()
if k not in {"default_model", _SETTINGS_PERSISTED_SPEECH_KEYS_FIELD}
}
# Persist speech keys only if they were already present on disk or explicitly
# submitted in this request. This avoids auto-materializing defaults during
# unrelated saves.
for speech_key in _SETTINGS_SPEECH_KEYS:
if speech_key not in effective_persisted_speech_keys:
persisted.pop(speech_key, None)
SETTINGS_FILE.parent.mkdir(parents=True, exist_ok=True) SETTINGS_FILE.parent.mkdir(parents=True, exist_ok=True)
SETTINGS_FILE.write_text( SETTINGS_FILE.write_text(
json.dumps(persisted, ensure_ascii=False, indent=2), json.dumps(persisted, ensure_ascii=False, indent=2),
@@ -8567,8 +8569,17 @@ if _settings_file_exists:
if _startup_settings.get("default_workspace") != str(DEFAULT_WORKSPACE): if _startup_settings.get("default_workspace") != str(DEFAULT_WORKSPACE):
_startup_settings["default_workspace"] = str(DEFAULT_WORKSPACE) _startup_settings["default_workspace"] = str(DEFAULT_WORKSPACE)
try: try:
startup_persisted_speech_keys = _extract_persisted_speech_keys(
_read_raw_settings_file()
)
SETTINGS_FILE.write_text( SETTINGS_FILE.write_text(
json.dumps(_startup_settings, ensure_ascii=False, indent=2), json.dumps(
_settings_payload_for_write(
_startup_settings, startup_persisted_speech_keys
),
ensure_ascii=False,
indent=2,
),
encoding="utf-8", encoding="utf-8",
) )
except Exception: except Exception:
@@ -187,6 +187,40 @@ def test_unrelated_settings_save_does_not_materialize_absent_speech_defaults():
_restore_settings_file(path, original) _restore_settings_file(path, original)
def test_startup_workspace_repair_write_drops_merged_speech_defaults():
path, original = _settings_file_snapshot()
cfg = importlib.import_module("api.config")
try:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
json.dumps(
{
"show_tps": False,
"tts_pitch": 0.0,
"default_workspace": "C:/stale/workspace",
},
ensure_ascii=False,
indent=2,
),
encoding="utf-8",
)
merged = cfg.load_settings()
merged["default_workspace"] = "C:/fixed/workspace"
persisted = cfg._settings_payload_for_write(
merged, cfg._extract_persisted_speech_keys(cfg._read_raw_settings_file())
)
assert persisted["show_tps"] is False
assert persisted["tts_pitch"] == 0.0
assert persisted["default_workspace"] == "C:/fixed/workspace"
assert PERSISTED_SPEECH_KEYS_FIELD not in persisted
for key in SPEECH_DEFAULTS:
if key != "tts_pitch":
assert key not in persisted
finally:
_restore_settings_file(path, original)
def test_invalid_speech_settings_preserve_previous_values_and_unrelated_settings(): def test_invalid_speech_settings_preserve_previous_values_and_unrelated_settings():
data, status = get("/api/settings") data, status = get("/api/settings")
original_show_tps = bool(data.get("show_tps")) original_show_tps = bool(data.get("show_tps"))