fix(gateway): config.yaml wins over .env for agent/display/timezone settings - #18764
Merged
Merged
Conversation
…ettings Regression from the silent config→env bridge. The bridge at module import time is correct for max_turns (unconditional overwrite), but every other agent.*, display.*, timezone, and security bridge key was guarded by 'if X not in os.environ' — so a stale .env entry from an old 'hermes setup' run would shadow the user's current config.yaml indefinitely. Symptom: agent.max_turns: 500 in config.yaml, HERMES_MAX_ITERATIONS=60 in .env from an old setup, and the gateway silently capped at 60 iterations per turn. Gateway logs confirmed api_calls never exceeded 60. Three changes: 1. gateway/run.py: drop the 'not in os.environ' guards for all agent.*, display.*, timezone, and security.* bridge keys. config.yaml is now authoritative for these settings — same semantics already in place for max_turns, terminal.*, and auxiliary.*. Also surface the bridge failure (previously 'except Exception: pass') to stderr so operators see bridge errors instead of silently falling back to .env. 2. gateway/run.py: INFO-log the resolved max_iterations at gateway start so operators can verify the config→env bridge did the right thing instead of chasing a phantom budget ceiling. 3. hermes_cli/setup.py: stop writing HERMES_MAX_ITERATIONS to .env in the setup wizard. config.yaml is the single source of truth. Also clean up any stale .env entry left behind by pre-fix setups. Regression tests in tests/gateway/test_config_env_bridge_authority.py guard each config→env key against the 'stale .env shadows config' bug.
1 task
waym0reom3ga
pushed a commit
to waym0reom3ga/autolycus-agent
that referenced
this pull request
May 8, 2026
…ettings (NousResearch#18764) Regression from the silent config→env bridge. The bridge at module import time is correct for max_turns (unconditional overwrite), but every other agent.*, display.*, timezone, and security bridge key was guarded by 'if X not in os.environ' — so a stale .env entry from an old 'hermes setup' run would shadow the user's current config.yaml indefinitely. Symptom: agent.max_turns: 500 in config.yaml, HERMES_MAX_ITERATIONS=60 in .env from an old setup, and the gateway silently capped at 60 iterations per turn. Gateway logs confirmed api_calls never exceeded 60. Three changes: 1. gateway/run.py: drop the 'not in os.environ' guards for all agent.*, display.*, timezone, and security.* bridge keys. config.yaml is now authoritative for these settings — same semantics already in place for max_turns, terminal.*, and auxiliary.*. Also surface the bridge failure (previously 'except Exception: pass') to stderr so operators see bridge errors instead of silently falling back to .env. 2. gateway/run.py: INFO-log the resolved max_iterations at gateway start so operators can verify the config→env bridge did the right thing instead of chasing a phantom budget ceiling. 3. hermes_cli/setup.py: stop writing HERMES_MAX_ITERATIONS to .env in the setup wizard. config.yaml is the single source of truth. Also clean up any stale .env entry left behind by pre-fix setups. Regression tests in tests/gateway/test_config_env_bridge_authority.py guard each config→env key against the 'stale .env shadows config' bug.
waym0reom3ga
pushed a commit
to waym0reom3ga/autolycus-agent
that referenced
this pull request
May 8, 2026
…ettings (NousResearch#18764) Regression from the silent config→env bridge. The bridge at module import time is correct for max_turns (unconditional overwrite), but every other agent.*, display.*, timezone, and security bridge key was guarded by 'if X not in os.environ' — so a stale .env entry from an old 'hermes setup' run would shadow the user's current config.yaml indefinitely. Symptom: agent.max_turns: 500 in config.yaml, HERMES_MAX_ITERATIONS=60 in .env from an old setup, and the gateway silently capped at 60 iterations per turn. Gateway logs confirmed api_calls never exceeded 60. Three changes: 1. gateway/run.py: drop the 'not in os.environ' guards for all agent.*, display.*, timezone, and security.* bridge keys. config.yaml is now authoritative for these settings — same semantics already in place for max_turns, terminal.*, and auxiliary.*. Also surface the bridge failure (previously 'except Exception: pass') to stderr so operators see bridge errors instead of silently falling back to .env. 2. gateway/run.py: INFO-log the resolved max_iterations at gateway start so operators can verify the config→env bridge did the right thing instead of chasing a phantom budget ceiling. 3. hermes_cli/setup.py: stop writing HERMES_MAX_ITERATIONS to .env in the setup wizard. config.yaml is the single source of truth. Also clean up any stale .env entry left behind by pre-fix setups. Regression tests in tests/gateway/test_config_env_bridge_authority.py guard each config→env key against the 'stale .env shadows config' bug.
8 tasks
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Gateway silently capped at 60 tool-calling iterations per turn despite
agent.max_turns: 500inconfig.yaml. Telegram/Discord sessions hit_handle_max_iterationsat exactly iteration 60 on every long turn. CLI (which readsagent.max_turnsdirectly) was unaffected.Root cause was a stale
HERMES_MAX_ITERATIONS=60entry left in.envby an oldhermes setuprun, combined with anot in os.environguard pattern in the gateway's config→env bridge that let the stale .env value silently shadow the currentconfig.yaml.Bridge Inconsistency
The config→env bridge at gateway import time (
gateway/run.py) was inconsistent across keys:max_turns→ unconditional overwrite (config wins) ✓gateway_timeout,gateway_timeout_warning,gateway_notify_interval,restart_drain_timeout,gateway_auto_continue_freshness→ guarded byif X not in os.environ(stale .env wins) ✗display.busy_input_mode,display.busy_ack_enabled→ guarded (stale .env wins) ✗timezone→ guarded (stale .env wins) ✗security.redact_secrets→ unconditional ✓The
except Exception: passat the bottom of the bridge also swallowed any partial bridge failures silently, meaning a raised exception anywhere in the block would skip subsequent keys and leave .env values in place — includingHERMES_MAX_ITERATIONS.Fix
1.
gateway/run.py— dropnot in os.environguards for allagent.*,display.*,timezone, andsecurity.*bridge keys.config.yamlis now authoritative for these, matching the semantics already in place formax_turns,terminal.*, andauxiliary.*. Also surface bridge failures to stderr instead ofpassso operators see breakage.2.
gateway/run.py— INFO-log the resolvedmax_iterationsat gateway start so operators can verify the bridge did the right thing instead of chasing a phantom budget ceiling:3.
hermes_cli/setup.py— stop writingHERMES_MAX_ITERATIONSto.envin the setup wizard.config.yamlis the single source of truth. Also proactively remove any stale.enventry left behind by pre-fix setups on next run.Tests
tests/gateway/test_config_env_bridge_authority.py(new, 166 lines) — regression tests for every bridge key, asserting config.yaml wins even when.envhas a conflicting value.tests/hermes_cli/test_setup_agent_settings.py(+55 lines) — covers the setup.pyHERMES_MAX_ITERATIONScleanup path.Verification
After the fix, running gateway logs:
Telegram sessions no longer cap at 60 tool calls per turn.