fix(#5435): stop startup workspace repair from persisting speech defaults
This commit is contained in:
1 parent
8f7b9c1d0d
commit
fdacb4b922
2 files changed
+57
-12
No files matched your search
+23
-12
@@ -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"))
|
||||||
|
|||||||
Reference in new issue
Block a user