Bug Description
/model switch is silently lost when it's the first message after a session auto-reset. The session DB shows the new model, the UI says the new model, but actual API calls go to the previous/default model.
Steps to Reproduce
- Have an active session that goes idle long enough to trigger auto-reset (or let it expire by inactivity)
- Send
/model <new_model> as the first message after the idle period
- The
/model command succeeds — UI shows "Model switched to X", session DB records the new model
- Send a regular message
- Actual: The response comes from the old model, not the one you switched to
- Check provider logs (e.g. OpenRouter dashboard) — zero calls to the new model
Expected Behavior
After /model switches the model, all subsequent messages in that session should use the new model.
Actual Behavior
The model override stored by /model is wiped on the next regular message because was_auto_reset is a sticky flag that never gets consumed.
Root Cause
In gateway/run.py, _handle_message_with_agent() (line ~8980):
if getattr(session_entry, "was_auto_reset", False):
self._session_model_overrides.pop(session_key, None) # ← wipes the override
self._set_session_reasoning_override(session_key, None)
if hasattr(self, "_pending_model_notes"):
self._pending_model_notes.pop(session_key, None)
This cleanup is designed to remove stale overrides from the previous session on auto-reset. But was_auto_reset is never consumed — it stays True for the entire session lifetime (unlike is_fresh_reset, which IS consumed at line ~8998 per issue #6508).
Timeline of the bug:
/model X arrives → get_or_create_session() auto-resets (idle session) → new session with was_auto_reset=True
_handle_model_command() correctly stores override: _session_model_overrides[key] = {model: X, ...}
- Next regular message →
_handle_message_with_agent() → was_auto_reset still True → pops the override
- Model resolution falls back to
config.yaml default
Two sources of truth diverge:
- Session DB (SQLite):
model = X (updated by _handle_model_command) → dashboard/UI shows X
- Runtime memory (
_session_model_overrides dict): empty → actual API calls use default model
Fix
Two-part patch (both in gateway/run.py):
1. Consume was_auto_reset after use (line ~9000)
After the _is_new_session check, consume the flag so it doesn't fire repeatedly:
if getattr(session_entry, "was_auto_reset", False):
session_entry.was_auto_reset = False
This mirrors the existing is_fresh_reset consumption pattern (#6508).
2. Clear was_auto_reset in _handle_model_command() (line ~11443)
After /model stores a new override, clear the flag so the next message handler doesn't wipe it:
try:
_override_sess_entry = self.session_store._entries.get(session_key)
if _override_sess_entry and getattr(_override_sess_entry, "was_auto_reset", False):
_override_sess_entry.was_auto_reset = False
except Exception:
pass
Environment
- Hermes Agent v0.16.0
- Platform: Matrix (likely affects all platforms: Telegram, Discord, etc.)
- Docker container (s6-overlay supervision)
Bug Description
/modelswitch is silently lost when it's the first message after a session auto-reset. The session DB shows the new model, the UI says the new model, but actual API calls go to the previous/default model.Steps to Reproduce
/model <new_model>as the first message after the idle period/modelcommand succeeds — UI shows "Model switched to X", session DB records the new modelExpected Behavior
After
/modelswitches the model, all subsequent messages in that session should use the new model.Actual Behavior
The model override stored by
/modelis wiped on the next regular message becausewas_auto_resetis a sticky flag that never gets consumed.Root Cause
In
gateway/run.py,_handle_message_with_agent()(line ~8980):This cleanup is designed to remove stale overrides from the previous session on auto-reset. But
was_auto_resetis never consumed — it staysTruefor the entire session lifetime (unlikeis_fresh_reset, which IS consumed at line ~8998 per issue #6508).Timeline of the bug:
/model Xarrives →get_or_create_session()auto-resets (idle session) → new session withwas_auto_reset=True_handle_model_command()correctly stores override:_session_model_overrides[key] = {model: X, ...}_handle_message_with_agent()→was_auto_resetstillTrue→ pops the overrideconfig.yamldefaultTwo sources of truth diverge:
model = X(updated by_handle_model_command) → dashboard/UI shows X_session_model_overridesdict): empty → actual API calls use default modelFix
Two-part patch (both in
gateway/run.py):1. Consume
was_auto_resetafter use (line ~9000)After the
_is_new_sessioncheck, consume the flag so it doesn't fire repeatedly:This mirrors the existing
is_fresh_resetconsumption pattern (#6508).2. Clear
was_auto_resetin_handle_model_command()(line ~11443)After
/modelstores a new override, clear the flag so the next message handler doesn't wipe it:Environment