personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(settings): mirror env var changes to os.environ on http save path

The HTTP /api/config save path wrote provider keys to journal.json but
never updated os.environ in the running supervisor — so a key saved via
the localhost:5015 wizard validated successfully yet /api/providers and
sol call settings providers reported configured:false until restart.

Mirrors the cli pattern in apps/settings/call.py:362-394 (set/clear).
After this, the wizard is self-sufficient — no service restart required
after pasting a key on a fresh install.

Regression test asserts os.environ reflects both set and clear in-process
through the http endpoint.

Refs req_uf5stjw7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+34
+5
apps/settings/routes.py
··· 229 229 if old_value != new_value: 230 230 changed_fields[key] = {"old": old_value, "new": new_value} 231 231 config[section][key] = new_value 232 + if section == "env": 233 + if new_value: 234 + os.environ[key] = new_value 235 + else: 236 + os.environ.pop(key, None) 232 237 233 238 # Hash password before writing to disk 234 239 if section == "convey" and "password" in data:
+29
tests/test_validate_key.py
··· 4 4 from __future__ import annotations 5 5 6 6 import json 7 + import os 7 8 from unittest.mock import Mock, patch 8 9 9 10 import pytest ··· 307 308 saved = json.loads(config_path.read_text()) 308 309 assert saved["providers"]["auth"]["google"] == "platform" 309 310 assert "google" not in saved["providers"]["key_validation"] 311 + 312 + 313 + def test_update_config_env_mirrors_os_environ(settings_client, monkeypatch): 314 + """The HTTP env-section save path must mirror into os.environ in-process, 315 + matching the CLI pattern (apps/settings/call.py keys_set/keys_clear). 316 + Without this, /api/providers reports `configured: false` until restart.""" 317 + client, _ = settings_client 318 + monkeypatch.delenv("GOOGLE_API_KEY", raising=False) 319 + 320 + with patch( 321 + "think.providers.validate_key", 322 + return_value={"valid": True}, 323 + ): 324 + response = client.put( 325 + "/app/settings/api/config", 326 + json={"section": "env", "data": {"GOOGLE_API_KEY": "live-key"}}, 327 + ) 328 + 329 + assert response.status_code == 200 330 + assert os.environ.get("GOOGLE_API_KEY") == "live-key" 331 + 332 + response = client.put( 333 + "/app/settings/api/config", 334 + json={"section": "env", "data": {"GOOGLE_API_KEY": ""}}, 335 + ) 336 + 337 + assert response.status_code == 200 338 + assert "GOOGLE_API_KEY" not in os.environ 310 339 311 340 312 341 def test_get_providers_includes_key_validation(settings_client):