From ef9a9831543f2bf46d59eb8afda0648fee0ac7bf Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Fri, 17 Jul 2026 08:02:29 -0700 Subject: [PATCH] fix(tui): route images with the live switched model --- .../test_image_routing_stale_model.py | 34 +++++++++++++++++++ tui_gateway/server.py | 19 +++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 tests/tui_gateway/test_image_routing_stale_model.py diff --git a/tests/tui_gateway/test_image_routing_stale_model.py b/tests/tui_gateway/test_image_routing_stale_model.py new file mode 100644 index 000000000000..ac465b26b693 --- /dev/null +++ b/tests/tui_gateway/test_image_routing_stale_model.py @@ -0,0 +1,34 @@ +"""Regression coverage for live TUI image-routing identity.""" + +from types import SimpleNamespace +from unittest.mock import patch + +from tui_gateway.server import _active_image_routing_identity + + +def test_live_agent_identity_wins_after_model_switch(): + agent = SimpleNamespace(provider="alibaba", model="qwen3.7-plus") + + with patch( + "agent.auxiliary_client._read_main_provider", + side_effect=AssertionError("stale provider fallback used"), + ), patch( + "agent.auxiliary_client._read_main_model", + side_effect=AssertionError("stale model fallback used"), + ): + identity = _active_image_routing_identity(agent) + + assert identity == ("alibaba", "qwen3.7-plus") + + +def test_missing_agent_identity_uses_runtime_fallback(): + agent = SimpleNamespace(provider="", model=None) + + with patch( + "agent.auxiliary_client._read_main_provider", return_value="openai-codex" + ), patch( + "agent.auxiliary_client._read_main_model", return_value="gpt-5.5-codex" + ): + identity = _active_image_routing_identity(agent) + + assert identity == ("openai-codex", "gpt-5.5-codex") diff --git a/tui_gateway/server.py b/tui_gateway/server.py index a70ead871a6b..ebbfae8e07a6 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -5091,6 +5091,16 @@ def _resolve_checkpoint_hash(mgr, cwd: str, ref: str) -> str: raise ValueError(f"Invalid checkpoint number. Use 1-{len(checkpoints)}.") +def _active_image_routing_identity(agent: Any) -> tuple[str, str]: + """Return the live provider/model, falling back before agent startup.""" + from agent.auxiliary_client import _read_main_model, _read_main_provider + + return ( + getattr(agent, "provider", "") or _read_main_provider(), + getattr(agent, "model", "") or _read_main_model(), + ) + + def _enrich_with_attached_images(user_text: str, image_paths: list[str]) -> str: """Pre-analyze attached images via vision and prepend descriptions to user text.""" import asyncio, json as _json @@ -9423,16 +9433,13 @@ def _run_prompt_submit(rid, sid: str, session: dict, text: Any) -> None: decide_image_input_mode, build_native_content_parts, ) - from agent.auxiliary_client import ( - _read_main_model, - _read_main_provider, - ) from hermes_cli.config import load_config as _tui_load_config _cfg = _tui_load_config() + _provider, _model = _active_image_routing_identity(agent) _mode = decide_image_input_mode( - _read_main_provider(), - _read_main_model(), + _provider, + _model, _cfg, ) if getattr(agent, "api_mode", "") == "codex_app_server":