fix(config): persist only the alias the runtime settings read

pydantic-settings takes the first alias present in the environment, even
when it is empty. persist_current() must save that same alias, so an empty
LLM_API_KEY does not let a non-empty OPENAI_API_KEY sibling land in the
file and restore a credential the run did not use.
This commit is contained in:
Ahmed Allam 2026-09-02 13:02:09 +00:00 committed by Ahmed Allam
parent 3e88e498b9
commit c514f712f4
2 changed files with 20 additions and 7 deletions

View file

@ -79,16 +79,13 @@ def persist_current() -> None:
continue
for finfo in type(sub_model).model_fields.values():
aliases = [alias.upper() for alias in _aliases_for(finfo)]
set_aliases = [alias for alias in aliases if os.environ.get(alias) is not None]
if not set_aliases:
active = next((alias for alias in aliases if alias in os.environ), None)
if active is None:
continue
for alias in aliases:
env_block.pop(alias, None)
for alias in set_aliases:
value = os.environ[alias]
if value:
env_block[alias] = value
break
if os.environ[active]:
env_block[active] = os.environ[active]
write_secret_text(target, json.dumps({"env": env_block}, indent=2))

View file

@ -364,6 +364,22 @@ def test_persist_current_empty_env_clears_file_value(
assert json.loads(target.read_text(encoding="utf-8")) == {"env": {"STRIX_LLM": "file-model"}}
def test_persist_current_empty_primary_alias_does_not_save_sibling(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
target = tmp_path / "cli-config.json"
target.write_text(json.dumps({"env": {"PERPLEXITY_API_KEY": "pplx"}}), encoding="utf-8")
loader.apply_config_override(target)
monkeypatch.setenv("LLM_API_KEY", "")
monkeypatch.setenv("OPENAI_API_KEY", "sibling-key")
assert loader.load_settings().llm.api_key == ""
loader.persist_current()
assert json.loads(target.read_text(encoding="utf-8")) == {"env": {"PERPLEXITY_API_KEY": "pplx"}}
def test_persist_current_replaces_corrupt_file(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None: