fix(tui-gateway): log when a client model override beats the profile default at session.create

The desktop composer's manual model pick rides into session.create as a
per-session override and silently wins over model.default for every new
chat. Name the override and the profile default in agent.log so the
choice is diagnosable from logs alone (#107410).
This commit is contained in:
Hermes Agent
2026-09-24 23:13:45 -05:00
committed by brooklyn!
parent 2896297189
commit 8a639e80fe
2 changed files with 26 additions and 0 deletions

View File

@@ -4,6 +4,8 @@ Before the gate the session was minted and the FIRST turn died with the provider
chat. Custom / unknown providers and same-family or unlisted names stay permissive.
"""
import logging
import pytest
@@ -55,3 +57,21 @@ def test_session_create_keeps_coherent_unlisted_and_custom_pairs(_create, params
assert "error" not in response, response
session = sessions[response["result"]["session_id"]]
assert session["model_override"] == {"model": params["model"], "provider": params["provider"]}
def test_session_create_logs_when_a_client_override_beats_the_profile_default(_create, caplog, monkeypatch):
"""A composer pick silently decided every new chat's model; agent.log must name it (#107410)."""
from tui_gateway import server
monkeypatch.setattr(server, "_session_default_model", lambda session: "deepseek-v4-flash")
with caplog.at_level(logging.INFO):
response, _ = _create({"model": "gpt-5.5", "provider": "openrouter"})
pinned = [r.getMessage() for r in caplog.records if "client override" in r.getMessage()]
caplog.clear()
_create({})
unpinned = [r.getMessage() for r in caplog.records if "client override" in r.getMessage()]
assert len(pinned) == 1
assert response["result"]["stored_session_id"] in pinned[0]
assert "gpt-5.5" in pinned[0] and "openrouter" in pinned[0] and "deepseek-v4-flash" in pinned[0]
assert unpinned == []

View File

@@ -402,6 +402,12 @@ def _create_session(rid, params: dict, *, copy_parent_history: bool = False) ->
"transport": current_transport() or _stdio_transport,
"auth_user_id": _transport_auth_user_id(current_transport())}
_register_session_cwd(_sessions[sid])
if session_model_override:
# A composer pick rides in as this override and beats model.default for the whole session;
# name both so agent.log alone explains which model a new chat runs, and why (#107410).
logger.info("session.create %s: model=%s provider=%s source=client override (profile default: %s)",
key, session_model_override["model"], session_model_override.get("provider") or "-",
_session_default_model(_sessions[sid]))
# No DB row here (drafts left "Untitled" litter): created on the first prompt — except seeded sessions.
# NOTE: we intentionally do NOT persist a DB row here. Every TUI/desktop launch (and every "New agent" /
# draft) opens a session here just to paint the composer, so eagerly creating a row left an "Untitled"