fix(settings): report live proxy configuration

This commit is contained in:
Sabee Ur Rehman Khan 2026-08-21 19:53:08 +05:00
parent 5e0ce242e9
commit e50d3cbabf
8 changed files with 221 additions and 26 deletions

View file

@ -390,7 +390,9 @@ def proxy_pipeline_kwargs(config: object) -> dict[str, object]:
return kwargs
def seed_proxy_env_defaults(env: MutableMapping[str, str] | None = None) -> None:
def seed_proxy_env_defaults(
env: MutableMapping[str, str] | None = None,
) -> frozenset[str]:
"""Seed the process env with the savings-profile defaults (default: coding).
Call at proxy EXECUTABLE entry points (the ``headroom proxy`` command and the
@ -403,9 +405,11 @@ def seed_proxy_env_defaults(env: MutableMapping[str, str] | None = None) -> None
keep clean (unseeded) defaults and test isolation is preserved.
"""
target = os.environ if env is None else env
before = set(target)
# apply_agent_savings_env_defaults honors an explicit HEADROOM_SAVINGS_PROFILE
# already in the env and otherwise falls back to DEFAULT_PROFILE (coding).
apply_agent_savings_env_defaults(target)
return frozenset(key for key in target if key not in before)
def with_target_savings(

View file

@ -174,6 +174,10 @@ class ProxyConfig:
# Optimization mode: "token" (rewrite for max compression) or
# "cache" (freeze prior turns for prefix-cache stability).
mode: str = "token"
# Environment keys generated by the savings profile at process startup.
# They are runtime defaults, not explicit operator exports; the settings
# schema uses this provenance to avoid reporting false env overrides.
profile_seeded_env_keys: frozenset[str] = field(default_factory=frozenset, repr=False)
# Optimization
optimize: bool = True

View file

@ -3670,7 +3670,10 @@ def create_app(config: ProxyConfig | None = None) -> FastAPI:
)
async def settings_schema(_request: Request):
"""Registry + grouped fields + effective values for the settings form."""
schema = settings_store.to_schema()
schema = settings_store.to_schema(
runtime_values=_settings_runtime_values(config),
env_override_exclusions=config.profile_seeded_env_keys,
)
# Tell the UI whether this is a supervised (docker/service) install, where
# manifest-baked knobs (HEADROOM_PORT/HEADROOM_HOST) are owned by the
# install manifest and must be rendered read-only. Foreground proxies
@ -5188,7 +5191,7 @@ def _json_ready(value: Any) -> Any:
return {field.name: _json_ready(getattr(value, field.name)) for field in fields(value)}
if isinstance(value, dict):
return {str(key): _json_ready(item) for key, item in value.items()}
if isinstance(value, list | tuple | set):
if isinstance(value, list | tuple | set | frozenset):
return [_json_ready(item) for item in value]
return value
@ -5209,6 +5212,51 @@ def _proxy_config_payload(config: ProxyConfig) -> dict[str, Any]:
return payload
_SETTINGS_CONFIG_ALIASES: dict[str, str] = {
"workers": "worker_processes",
"rpm": "rate_limit_requests_per_minute",
"tpm": "rate_limit_tokens_per_minute",
"budget": "budget_limit_usd",
"log_messages": "log_full_messages",
"ccr_inline_resolve": "ccr_resolve_markers_inline",
"subscription_poll_interval": "subscription_poll_interval_s",
"request_timeout": "request_timeout_seconds",
"min_evidence": "traffic_learning_min_evidence",
"memory_project_root": "memory_project_root_override",
"anthropic_base_url": "anthropic_api_url",
"openai_base_url": "openai_api_url",
"region": "bedrock_region",
}
def _settings_runtime_values(config: ProxyConfig) -> dict[str, Any]:
"""Project the live proxy config onto the curated settings registry."""
from headroom import settings_store
values: dict[str, Any] = {}
for setting in settings_store.SETTINGS:
attribute = _SETTINGS_CONFIG_ALIASES.get(setting.key, setting.key)
if not hasattr(config, attribute):
continue
value = getattr(config, attribute)
if isinstance(value, set | frozenset):
value = ",".join(sorted(value))
values[setting.key] = value
values.update(
{
"no_ccr": not (
config.ccr_inject_tool or config.ccr_inject_marker or config.ccr_handle_responses
),
"no_ccr_proactive_expansion": not config.ccr_proactive_expansion,
"no_subscription_tracking": not config.subscription_tracking_enabled,
"no_memory_tools": not config.memory_inject_tools,
"no_memory_context": not config.memory_inject_context,
}
)
return values
def _proxy_config_from_env() -> ProxyConfig:
raw_config = os.environ.get(_MULTI_WORKER_CONFIG_ENV)
if raw_config:
@ -5221,6 +5269,8 @@ def _proxy_config_from_env() -> ProxyConfig:
from headroom.rollout import RolloutSnapshot
values["rollout"] = RolloutSnapshot.from_internal_dict(rollout_value)
if "profile_seeded_env_keys" in values:
values["profile_seeded_env_keys"] = frozenset(values["profile_seeded_env_keys"])
return ProxyConfig(**values)
except (KeyError, TypeError, ValueError, json.JSONDecodeError):
logger.warning(
@ -5296,8 +5346,12 @@ def create_app_from_env() -> FastAPI:
# tool-search, dedupe, read protection, …). setdefault → explicit env wins.
from headroom.agent_savings import seed_proxy_env_defaults
seed_proxy_env_defaults()
return create_app(_proxy_config_from_env())
seeded_env_keys = seed_proxy_env_defaults()
config = _proxy_config_from_env()
config.profile_seeded_env_keys = frozenset(
set(config.profile_seeded_env_keys) | set(seeded_env_keys)
)
return create_app(config)
def _get_code_aware_banner_status(config: ProxyConfig) -> str:
@ -5364,9 +5418,12 @@ def run_server(
# already resolved into `config` above via their inline defaults.
from headroom.agent_savings import seed_proxy_env_defaults
seed_proxy_env_defaults()
seeded_env_keys = seed_proxy_env_defaults()
config = config or ProxyConfig()
config.profile_seeded_env_keys = frozenset(
set(config.profile_seeded_env_keys) | set(seeded_env_keys)
)
if workers < 1:
raise ValueError("workers must be >= 1")
config.worker_processes = workers

View file

@ -63,6 +63,20 @@ class SettingField:
# the body-resolved HEADROOM_CODE_AWARE_ENABLED reader both accept).
SETTINGS: tuple[SettingField, ...] = (
# --- Compression ---
SettingField(
"HEADROOM_MODE",
"mode",
"Proxy mode",
"Compression",
"enum",
default="cache",
choices=("token", "cache"),
help=(
"Optimization posture: token rewrites history for maximum compression; "
"cache preserves prior turns for prefix-cache stability."
),
tier="basic",
),
SettingField(
"HEADROOM_SAVINGS_PROFILE",
"savings_profile",
@ -947,8 +961,25 @@ def apply_to_environ(values: dict[str, Any]) -> None:
os.environ.setdefault(field.env, _serialize(field, value))
def effective_values(stored: dict[str, Any] | None = None) -> dict[str, Any]:
"""The value actually active now for each knob: default ← file ← environ."""
def _coerce_runtime_values(runtime_values: dict[str, Any] | None) -> dict[str, Any]:
"""Coerce known live-config values without exposing invalid internal state."""
result: dict[str, Any] = {}
for key, value in (runtime_values or {}).items():
field = _BY_KEY.get(key)
if field is None:
continue
try:
result[key] = _coerce(field, value)
except (ValueError, TypeError):
continue
return result
def effective_values(
stored: dict[str, Any] | None = None,
runtime_values: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""The active value for each knob: default ← file ← environ ← runtime."""
if stored is None:
stored = load()
result: dict[str, Any] = {}
@ -961,6 +992,7 @@ def effective_values(stored: dict[str, Any] | None = None) -> dict[str, Any]:
except (ValueError, TypeError):
pass # unparseable env: keep the file/default value
result[field.key] = value
result.update(_coerce_runtime_values(runtime_values))
return result
@ -978,14 +1010,26 @@ def stored_values(mask_secrets: bool = True) -> dict[str, Any]:
return {key: _mask(_BY_KEY[key], value) for key, value in values.items()}
def to_schema() -> dict[str, Any]:
def to_schema(
*,
runtime_values: dict[str, Any] | None = None,
env_override_exclusions: set[str] | frozenset[str] = frozenset(),
) -> dict[str, Any]:
"""Registry + grouped fields + effective values for the UI. Secrets masked.
All curated knobs are startup-captured, so every key is restart-required;
``needs_restart_keys`` lists them for the UI's "restart to apply" banner.
``runtime_values`` is the live ``ProxyConfig`` tier. It wins over values
re-read from ``os.environ``, which can contain profile defaults that were
seeded only after CLI options had already been resolved. Those generated
defaults belong in ``env_override_exclusions`` so they are not presented as
explicit operator exports.
"""
stored = load()
effective = effective_values(stored)
environment_effective = effective_values(stored)
runtime = _coerce_runtime_values(runtime_values)
effective = {**environment_effective, **runtime}
fields: list[dict[str, Any]] = []
for field in SETTINGS:
fields.append(
@ -1003,7 +1047,10 @@ def to_schema() -> dict[str, Any]:
"minimum": field.minimum,
"maximum": field.maximum,
"tier": field.tier,
"env_override": bool(os.environ.get(field.env)),
"env_override": bool(os.environ.get(field.env))
and field.env not in env_override_exclusions,
"runtime_override": field.key in runtime
and runtime[field.key] != environment_effective[field.key],
"value": _mask(field, effective.get(field.key)),
"stored": _mask(field, stored.get(field.key)),
}

View file

@ -15,6 +15,7 @@ from headroom.agent_savings import (
apply_agent_savings_profile,
get_agent_savings_profile,
proxy_pipeline_kwargs,
seed_proxy_env_defaults,
with_target_savings,
)
from headroom.cli import wrap as wrap_module
@ -171,6 +172,18 @@ def test_agent_savings_env_defaults_preserve_user_overrides() -> None:
assert env["HEADROOM_SMART_CRUSHER_COMPACTION"] == "0"
def test_seed_proxy_env_defaults_reports_only_generated_keys() -> None:
env = {"HEADROOM_MODE": "token", "HEADROOM_LOSSLESS": "1"}
seeded = seed_proxy_env_defaults(env)
assert "HEADROOM_MODE" not in seeded
assert "HEADROOM_LOSSLESS" not in seeded
assert "HEADROOM_SAVINGS_PROFILE" in seeded
assert env["HEADROOM_MODE"] == "token"
assert env["HEADROOM_LOSSLESS"] == "1"
def test_unknown_agent_savings_profile_falls_back_to_default(
caplog: pytest.LogCaptureFixture,
) -> None:

View file

@ -175,6 +175,45 @@ class TestEffectiveValues:
monkeypatch.setenv("HEADROOM_SAVINGS_PROFILE", "general")
assert settings_store.effective_values()["savings_profile"] == "general"
def test_runtime_values_override_environment(self, workspace, monkeypatch):
_clear_env(monkeypatch)
monkeypatch.setenv("HEADROOM_LOSSLESS", "0")
values = settings_store.effective_values(runtime_values={"lossless": True})
assert values["lossless"] is True
def test_schema_marks_runtime_difference_without_mislabeling_seeded_env(
self, workspace, monkeypatch
):
_clear_env(monkeypatch)
monkeypatch.setenv("HEADROOM_MODE", "cache")
monkeypatch.setenv("HEADROOM_LOSSLESS", "0")
schema = settings_store.to_schema(
runtime_values={"mode": "token", "lossless": True},
env_override_exclusions={"HEADROOM_MODE", "HEADROOM_LOSSLESS"},
)
by_key = {field["key"]: field for field in schema["fields"]}
assert by_key["mode"]["value"] == "token"
assert by_key["mode"]["runtime_override"] is True
assert by_key["mode"]["env_override"] is False
assert by_key["lossless"]["value"] is True
assert by_key["lossless"]["runtime_override"] is True
assert by_key["lossless"]["env_override"] is False
def test_schema_keeps_explicit_environment_override(self, workspace, monkeypatch):
_clear_env(monkeypatch)
monkeypatch.setenv("HEADROOM_LOSSLESS", "1")
schema = settings_store.to_schema(runtime_values={"lossless": True})
lossless = next(field for field in schema["fields"] if field["key"] == "lossless")
assert lossless["value"] is True
assert lossless["runtime_override"] is False
assert lossless["env_override"] is True
class TestSecretMasking:
def test_schema_and_stored_mask_secret(self, workspace, monkeypatch):

View file

@ -21,20 +21,24 @@ from headroom import settings_store # noqa: E402
from headroom.proxy.server import ProxyConfig, create_app # noqa: E402
def _make_app():
return create_app(
ProxyConfig(
optimize=False,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
ccr_inject_tool=False,
ccr_handle_responses=False,
ccr_context_tracking=False,
image_optimize=False,
)
)
def _make_config(**overrides):
values = {
"optimize": False,
"cache_enabled": False,
"rate_limit_enabled": False,
"cost_tracking_enabled": False,
"log_requests": False,
"ccr_inject_tool": False,
"ccr_handle_responses": False,
"ccr_context_tracking": False,
"image_optimize": False,
}
values.update(overrides)
return ProxyConfig(**values)
def _make_app(**overrides):
return create_app(_make_config(**overrides))
@pytest.fixture
@ -77,6 +81,28 @@ class TestSchemaAndRead:
assert resp.status_code == 200, resp.text
assert resp.json() == {"target_ratio": 0.5, "savings_profile": "balanced"}
def test_schema_reports_live_config_and_seed_provenance(self, workspace, monkeypatch):
monkeypatch.setenv("HEADROOM_MODE", "cache")
monkeypatch.setenv("HEADROOM_LOSSLESS", "0")
app = _make_app(
mode="token",
lossless=True,
worker_processes=2,
profile_seeded_env_keys=frozenset({"HEADROOM_MODE", "HEADROOM_LOSSLESS"}),
)
client = TestClient(app, base_url="http://127.0.0.1", client=("127.0.0.1", 12345))
resp = client.get("/settings/schema")
assert resp.status_code == 200, resp.text
by_key = {field["key"]: field for field in resp.json()["fields"]}
assert by_key["mode"]["value"] == "token"
assert by_key["mode"]["env_override"] is False
assert by_key["lossless"]["value"] is True
assert by_key["lossless"]["runtime_override"] is True
assert by_key["lossless"]["env_override"] is False
assert by_key["workers"]["value"] == 2
class TestEndpointsGroup:
def test_schema_includes_endpoints_group_and_secret_flags(self, client):

View file

@ -223,7 +223,11 @@ def test_multi_worker_config_round_trip_preserves_typed_rollout(monkeypatch) ->
"HEADROOM_DISABLE_FEATURES": "read_maturation",
}
)
original = ProxyConfig(rollout=rollout, worker_processes=2)
original = ProxyConfig(
rollout=rollout,
worker_processes=2,
profile_seeded_env_keys=frozenset({"HEADROOM_MODE", "HEADROOM_LOSSLESS"}),
)
monkeypatch.setenv(_MULTI_WORKER_CONFIG_ENV, json.dumps(_proxy_config_payload(original)))
restored = _proxy_config_from_env()
@ -233,6 +237,7 @@ def test_multi_worker_config_round_trip_preserves_typed_rollout(monkeypatch) ->
assert restored.rollout.is_enabled("proxy_output_shaper") is True
assert restored.rollout.is_enabled("read_maturation") is False
assert restored.worker_processes == 2
assert restored.profile_seeded_env_keys == frozenset({"HEADROOM_MODE", "HEADROOM_LOSSLESS"})
def test_documented_proxy_json_without_internal_snapshot_is_preserved(monkeypatch) -> None: