refactor(cli): one stored_session_route for interactive and one-shot resume

_apply_stored_session_runtime was a line-for-line copy of the first half of
_restore_session_model (stored-model guard, session_gateway_runtime, bare-custom heal,
model/provider-changed check). Extract that pure decision into
cli_model_switch_mixin.stored_session_route and have both resume paths call it; the
one-shot keeps only the _ModelChoice mapping and the drop-ambient-key rule.

main.py stops re-normalising `resume` — _resolve_chat_session_args already did.
Tests trimmed from 20 to 13: near-duplicate unit tests of the private helpers go, the
end-to-end _run_agent contracts (stored runtime + reopen; explicit --model wins) and the
empty-session-keeps-id case stay.
This commit is contained in:
kshitijk4poor
2026-09-09 11:44:01 +05:30
committed by kshitij
parent 8aa773af89
commit 32273b8118
4 changed files with 37 additions and 112 deletions
+23 -14
View File
@@ -28,6 +28,25 @@ def _runtime_fields(cli) -> dict:
return {key: getattr(cli, key, None) for key in _RUNTIME_FIELDS}
def stored_session_route(session_meta, *, current_model, current_provider):
"""The route a resumed session should run on, or ``None`` when the stored one is absent or
already current. Returns ``(model, provider, base_url, api_mode, provider_changed)``; the
canonical row reader is ``SessionDB.session_gateway_runtime`` (``model_config.gateway_runtime``,
else the TUI's top-level keys). Bare ``custom`` is healed because the CLI resolve path
hard-fails on it (the TUI gateway keeps it when a base_url exists)."""
stored_model = str((session_meta or {}).get("model") or "").strip()
if not stored_model:
return None
from hermes_state import SessionDB as _SessionDB
runtime = _SessionDB.session_gateway_runtime(session_meta)
base_url = runtime.get("base_url") or None
provider = _heal_bare_custom_provider(runtime.get("provider") or None, base_url=base_url, model=stored_model)
provider_changed = bool(provider) and provider != current_provider
if stored_model == current_model and not provider_changed:
return None
return stored_model, provider, base_url, (runtime.get("api_mode") or None), provider_changed
def _heal_bare_custom_provider(provider, *, base_url, model):
"""Bare ``custom`` is a billing class, not a routable identity: persisting/restoring it makes a
later resume hard-fail once the config default leaves the custom endpoint. Recover the durable
@@ -348,22 +367,12 @@ class CLIModelSwitchMixin:
so the session still opens (the first turn surfaces the auth error).
"""
from cli import logger
stored_model = (session_meta or {}).get("model")
if not stored_model or getattr(self, "_explicit_model_override", False):
if getattr(self, "_explicit_model_override", False):
return
# Canonical row reader: model_config.gateway_runtime, else the TUI's top-level keys.
from hermes_state import SessionDB as _SessionDB
_stored_runtime = _SessionDB.session_gateway_runtime(session_meta)
stored_base_url = _stored_runtime.get("base_url") or None
stored_api_mode = _stored_runtime.get("api_mode") or None
# Stricter than the TUI gateway's recovery (which keeps bare "custom" when a
# base_url exists) — the CLI's resolve path would hard-fail on it.
stored_provider = _heal_bare_custom_provider(
_stored_runtime.get("provider") or None, base_url=stored_base_url, model=stored_model)
model_changed = stored_model != self.model
provider_changed = bool(stored_provider) and stored_provider != self.provider
if not model_changed and not provider_changed:
route = stored_session_route(session_meta, current_model=self.model, current_provider=self.provider)
if route is None:
return
stored_model, stored_provider, stored_base_url, stored_api_mode, provider_changed = route
self.model = stored_model
if stored_provider:
self.provider = stored_provider