From b583210c974b7143cccb8e32a3e50992393b5a66 Mon Sep 17 00:00:00 2001 From: asheriif Date: Sun, 12 Apr 2026 11:50:24 +0000 Subject: [PATCH] fix(gateway): fix regression causing display.streaming to override root streaming key --- gateway/display_config.py | 15 +++++++++++---- tests/gateway/test_display_config.py | 9 +++++++++ tests/gateway/test_run_progress_topics.py | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/gateway/display_config.py b/gateway/display_config.py index c1dcf2a64..78e8bc9af 100644 --- a/gateway/display_config.py +++ b/gateway/display_config.py @@ -9,6 +9,10 @@ Resolution order (first non-None wins): 3. ``_PLATFORM_DEFAULTS[][]`` — built-in sensible default 4. ``_GLOBAL_DEFAULTS[]`` — built-in global default +Exception: ``display.streaming`` is CLI-only. Gateway streaming follows the +top-level ``streaming`` config unless ``display.platforms..streaming`` +sets an explicit per-platform override. + Backward compatibility: ``display.tool_progress_overrides`` is still read as a fallback for ``tool_progress`` when no ``display.platforms`` entry exists. A config migration (version bump) automatically moves the old format into the new @@ -143,10 +147,13 @@ def resolve_display_setting( if val is not None: return _normalise(setting, val) - # 2. Global user setting (display.) - val = display_cfg.get(setting) - if val is not None: - return _normalise(setting, val) + # 2. Global user setting (display.). Skip display.streaming because + # that key controls only CLI terminal streaming; gateway token streaming is + # governed by the top-level streaming config plus per-platform overrides. + if setting != "streaming": + val = display_cfg.get(setting) + if val is not None: + return _normalise(setting, val) # 3. Built-in platform default plat_defaults = _PLATFORM_DEFAULTS.get(platform_key) diff --git a/tests/gateway/test_display_config.py b/tests/gateway/test_display_config.py index ae2eac66e..2192d67bc 100644 --- a/tests/gateway/test_display_config.py +++ b/tests/gateway/test_display_config.py @@ -297,6 +297,15 @@ class TestStreamingPerPlatform: result = resolve_display_setting(config, "telegram", "streaming") assert result is None # caller should check global StreamingConfig + def test_global_display_streaming_is_cli_only(self): + """display.streaming must not act as a gateway streaming override.""" + from gateway.display_config import resolve_display_setting + + for value in (True, False): + config = {"display": {"streaming": value}} + assert resolve_display_setting(config, "telegram", "streaming") is None + assert resolve_display_setting(config, "discord", "streaming") is None + def test_explicit_false_disables(self): """Explicit False disables streaming for that platform.""" from gateway.display_config import resolve_display_setting diff --git a/tests/gateway/test_run_progress_topics.py b/tests/gateway/test_run_progress_topics.py index 7859edd74..1b7829616 100644 --- a/tests/gateway/test_run_progress_topics.py +++ b/tests/gateway/test_run_progress_topics.py @@ -572,6 +572,27 @@ async def test_run_agent_streaming_does_not_enable_completed_interim_commentary( assert not any(call["content"] == "I'll inspect the repo first." for call in adapter.sent) +@pytest.mark.asyncio +async def test_display_streaming_does_not_enable_gateway_streaming(monkeypatch, tmp_path): + adapter, result = await _run_with_agent( + monkeypatch, + tmp_path, + CommentaryAgent, + session_id="sess-display-streaming-cli-only", + config_data={ + "display": { + "streaming": True, + "interim_assistant_messages": True, + }, + "streaming": {"enabled": False}, + }, + ) + + assert result.get("already_sent") is not True + assert adapter.edits == [] + assert [call["content"] for call in adapter.sent] == ["I'll inspect the repo first."] + + @pytest.mark.asyncio async def test_run_agent_interim_commentary_works_with_tool_progress_off(monkeypatch, tmp_path): adapter, result = await _run_with_agent(