fix(gateway): scope session-only /model context_length to configured route - #48187
fix(gateway): scope session-only /model context_length to configured route#48187ele-yufo wants to merge 5 commits into
Conversation
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Scopes the session-only /model context_length to the configured route in the gateway, preventing cross-session context length bleed.
Looks Good
- Clean fix, 2 files
- Correct scoping behavior
- No side effects
Reviewed by Hermes Agent
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating both gateway confirmation paths. The route-mismatch premise is still present on current main: gateway/slash_commands.py:1686-1703 and gateway/slash_commands.py:1940-1957 pass the global override unconditionally.
Problems
tests/gateway/test_model_command_context_scope.py:79does not include--session. Currentresolve_persist_behavior()persists plain/modelcommands by default (hermes_cli/model_switch.py:416-443), so this no longer proves the stated session-only case.- Current main writes
model.defaultandmodel.providerbefore confirmation construction (gateway/slash_commands.py:1897-1927; picker equivalent at1650-1676). Reloading config in the proposed guard afterward sees the new target route and accepts the inheritedcontext_lengthfor persistent switches.
Suggested changes
- Add
--sessionto the regression and assert the original config route remains unchanged. - Salvage against current persistence ordering by using pre-switch route state for the session-only check, while keeping global behavior explicitly scoped.
Automated hermes-sweeper review.
| monkeypatch.setattr("hermes_cli.model_switch.switch_model", lambda **kw: _codex_switch_result()) | ||
| monkeypatch.setattr("hermes_cli.model_cost_guard.expensive_model_warning", lambda *a, **kw: None) | ||
|
|
||
| result = await _make_runner()._handle_model_command(_make_event("/model gpt-5.5 --provider openai-codex")) |
There was a problem hiding this comment.
Please add --session here. Current main persists a plain /model switch by default (hermes_cli/model_switch.py:416-443), so this command does not exercise the session-only behavior described by the test and PR.
PR NousResearch#48187 hermes-sweeper review: the session-only regression should carry --session and assert the configured route survives the switch, and the pre-switch route-state guard should keep persistent switches explicitly scoped. The capture-at-start refactor on this branch already resolves both the session-only display check and the global persist through pre-switch config (should_clear_context_pin), so this adds the matching regression coverage: - the --session test now also asserts config.yaml is untouched afterward - a new --global test proves the stale 1M context_length is neither shown (confirmation reports Codex's real 272K cap) nor inherited (the route-mismatched pin is dropped from the persisted config)
|
Follow-up after hermes-sweeper review (keep_open, salvageability=medium): What changed:
Test results: target file 2 passed; adjacent cluster (persist_default / global_switch_persists / apply_result_context / context_offload / custom_provider_context_length) 20 passed, 0 failed; ruff check + format clean. @teknium1 could you re-run the sweeper against the updated head? |
Summary
Fix session-scoped
/modelcontext-length resolution so a globalmodel.context_lengthoverride does not bleed into unrelated runtime routes.Symptoms
With this config:
a session-only gateway switch like:
previously showed 1,000,000 tokens, even though Codex OAuth
gpt-5.5should resolve through the provider-aware path (272K in current Hermes metadata).What this PR changes
Only the gateway confirmation path for
/modelis changed.Added
_config_context_length_for_target()ingateway/slash_commands.pyto return the globalmodel.context_lengthoverride only when it belongs to the same configured route (model.default+model.provider).Both call sites that previously unconditionally passed the global
model.context_lengthintoresolve_display_context_length()now call this guard instead.What this PR intentionally does NOT change
agent_init.py/ global default semantics.This PR fixes the narrower route-mismatch bug for session-only
/modelswitches.Why this matters
Global context overrides are useful, but they are route-specific in practice. A 1M override for one provider/model should not silently transfer to a different provider route whose real enforced cap is different.
This matters especially for Codex routes, where provider-aware context caps differ from direct-API OpenRouter/OpenAI metadata.
Related upstream issues
This fix is closely related to, but narrower than, several existing open issues/PRs:
In particular, it addresses the session-only
/modelroute mismatch path rather than the broader--globalstale-override family.Verification
tests/gateway/test_model_command_context_scope.pytests/gateway/test_model_command_context_scope.pytests/gateway/test_model_command_flat_string_config.pytests/hermes_cli/test_model_switch_context_display.pytests/agent/test_model_metadata.py::TestCodexOAuthContextLengthtests/gateway/test_model_command_custom_providers.pytests/gateway/test_model_switch_persistence.pytests/hermes_cli/test_model_switch_custom_providers.pyExample local result during verification:
Scope discipline
gateway/slash_commands.pybehavior and one new test file are included.Notes
This PR intentionally does not close the broader
--globalstalemodel.context_lengthcleanup family; that is a larger, pre-existing upstream problem.