From 794519c6ad4918b5c7a5475f8ddd0052be9a54e5 Mon Sep 17 00:00:00 2001 From: lengr Date: Sat, 30 May 2026 13:52:07 +0800 Subject: [PATCH] fix(state): persist mid-session model switch to database When a user switches models mid-session via /model, the gateway updates the in-memory agent and session overrides, but the database was never updated. The COALESCE(model, ?) in update_token_counts() only fills NULL values, so the dashboard always showed the original model. Fix: Add SessionDB.update_session_model() that unconditionally sets the model column, and call it from both the interactive picker and direct /model command paths in the gateway. Fixes #34850 --- gateway/run.py | 29 +++++++++++++++++++++++++++++ hermes_state.py | 14 ++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/gateway/run.py b/gateway/run.py index 1b2220a56..514110a83 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -10549,6 +10549,22 @@ class GatewayRunner: except Exception as exc: logger.warning("Picker model switch failed for cached agent: %s", exc) + # Persist the new model to the session DB so the + # dashboard shows the updated model (#34850). + _sess_db = getattr(_self, "_session_db", None) + if _sess_db is not None: + try: + _sess_entry = _self.session_store.get_or_create_session( + event.source + ) + _sess_db.update_session_model( + _sess_entry.session_id, result.new_model + ) + except Exception as exc: + logger.debug( + "Failed to persist model switch to DB: %s", exc + ) + # Store model note + session override if not hasattr(_self, "_pending_model_notes"): _self._pending_model_notes = {} @@ -10686,6 +10702,19 @@ class GatewayRunner: except Exception as exc: logger.warning("In-place model switch failed for cached agent: %s", exc) + # Persist the new model to the session DB so the dashboard + # shows the updated model (#34850). + if self._session_db is not None: + try: + _sess_entry = self.session_store.get_or_create_session(source) + self._session_db.update_session_model( + _sess_entry.session_id, result.new_model + ) + except Exception as exc: + logger.debug( + "Failed to persist model switch to DB: %s", exc + ) + # Store a note to prepend to the next user message so the model # knows about the switch (avoids system messages mid-history). if not hasattr(self, "_pending_model_notes"): diff --git a/hermes_state.py b/hermes_state.py index 19f207632..771ded991 100644 --- a/hermes_state.py +++ b/hermes_state.py @@ -965,6 +965,20 @@ class SessionDB: ) self._execute_write(_do) + def update_session_model(self, session_id: str, model: str) -> None: + """Update the model for a session after a mid-session switch. + + Unlike ``update_token_counts`` which uses ``COALESCE(model, ?)`` + (only filling in NULL), this unconditionally sets the model column + so that the dashboard reflects the user's latest /model choice. + """ + def _do(conn): + conn.execute( + "UPDATE sessions SET model = ? WHERE id = ?", + (model, session_id), + ) + self._execute_write(_do) + def update_token_counts( self, session_id: str,