From ccfb68688eaf33e6a693b7ae38f48b7ee617bafe Mon Sep 17 00:00:00 2001 From: Semir Kabir Date: Fri, 28 Aug 2026 04:18:10 +0000 Subject: [PATCH] fix(photon): stop advertising fenced code-block support on iMessage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gateway's tool-progress path emits terminal commands as fenced code blocks on any adapter whose supports_code_blocks is True. The Photon adapter set that flag from PHOTON_MARKDOWN, but the sidecar's /send router (send-format.mjs) silently routes every URL-bearing message through the plain-text builder — where fences survive as literal backtick characters — and even the markdown path renders a fence as inline monospace text, not a block. Net effect: raw fenced terminal commands (and raw markdown around them) surfaced in iMessage bubbles no matter what the user's prompt-level style rules said. Fix the whole class: the adapter never claims code-block support, so the gateway emits its compact one-line tool preview instead. Prose markdown passthrough (bold/italic/headings) is unchanged, and no config change is required — tool_progress can stay at its user's preferred mode. Tests: new capability + E2E tests pin that the gateway cannot emit a fence for Photon with real adapter + real display resolution; the old supports_code_blocks-mirrors-env expectation (which pinned the buggy behavior) now asserts the flag is always False. --- plugins/platforms/photon/adapter.py | 4 +++- tests/plugins/platforms/photon/test_markdown.py | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/platforms/photon/adapter.py b/plugins/platforms/photon/adapter.py index ed74e0f349..39a41e6c2e 100644 --- a/plugins/platforms/photon/adapter.py +++ b/plugins/platforms/photon/adapter.py @@ -527,7 +527,9 @@ class PhotonAdapter(BasePlatformAdapter): self._probe_timeout = _setting("probe_timeout_seconds", "PHOTON_PROBE_TIMEOUT_SECONDS", 10.0, float) self._probe_max_failures = _setting("probe_max_failures", "PHOTON_PROBE_MAX_FAILURES", 3, int) self._probe_enabled = self._probe_interval > 0 - self.supports_code_blocks = _markdown_enabled() # markdown on => fences pass through + # Never advertise fences: a URL-bearing message goes out as raw text (literal ```), and the + # markdown path renders a fence as inline Unicode monospace, not a block. + self.supports_code_blocks = False self._sidecar_proc: Optional[subprocess.Popen] = None self._http_client: Optional["httpx.AsyncClient"] = None self._respawn_lock: Optional[asyncio.Lock] = None diff --git a/tests/plugins/platforms/photon/test_markdown.py b/tests/plugins/platforms/photon/test_markdown.py index 5fd688aeb7..50e0b7041f 100644 --- a/tests/plugins/platforms/photon/test_markdown.py +++ b/tests/plugins/platforms/photon/test_markdown.py @@ -43,9 +43,16 @@ def test_format_message_passthrough_by_default( assert adapter.format_message(_MD) == _MD -def test_supports_code_blocks_mirrors_env(monkeypatch: pytest.MonkeyPatch) -> None: +def test_supports_code_blocks_never_enabled( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Fenced code blocks are not renderable on iMessage: URL-bearing + messages fall back to raw text (literal fences), and the markdown path + renders a fence as inline monospace, not a block. The adapter therefore + never advertises code-block support — the gateway emits its compact + one-line tool preview instead (see test_code_block_capability.py).""" monkeypatch.delenv("PHOTON_MARKDOWN", raising=False) - assert _make_adapter(monkeypatch).supports_code_blocks is True + assert _make_adapter(monkeypatch).supports_code_blocks is False monkeypatch.setenv("PHOTON_MARKDOWN", "false") assert _make_adapter(monkeypatch).supports_code_blocks is False