From f5bd09af4b37c4d77c1900a6d66eea80d008e8a3 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sun, 7 Jun 2026 19:50:08 -0700 Subject: [PATCH] refactor(acp): share interrupt-sentinel prefix, simplify guard Replace the ACP-local prefix/suffix matcher + helper with a single startswith() check against INTERRUPT_WAITING_FOR_MODEL_PREFIX, now defined once in conversation_loop.py where the sentinel is produced. Keeps the source of truth in one place so the guard cannot drift if the status string changes. Net -17 LOC in server.py. Also add lsaether to release.py AUTHOR_MAP. --- acp_adapter/server.py | 22 ++++++---------------- agent/conversation_loop.py | 7 ++++++- scripts/release.py | 1 + 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/acp_adapter/server.py b/acp_adapter/server.py index 1e699f61729..b4195af87d8 100644 --- a/acp_adapter/server.py +++ b/acp_adapter/server.py @@ -88,20 +88,6 @@ _executor = ThreadPoolExecutor(max_workers=4, thread_name_prefix="acp-agent") # does not expose a client-side limit, so this is a fixed cap that clients # paginate against using `cursor` / `next_cursor`. _LIST_SESSIONS_PAGE_SIZE = 50 -_INTERRUPT_WAITING_FOR_MODEL_PREFIX = ( - "Operation interrupted: waiting for model response (" -) -_INTERRUPT_WAITING_FOR_MODEL_SUFFIX = " elapsed)." - - -def _is_interrupt_waiting_for_model_response(text: Any) -> bool: - """Return True for Hermes' local API-wait interruption status string.""" - response = str(text or "").strip() - return ( - response.startswith(_INTERRUPT_WAITING_FOR_MODEL_PREFIX) - and response.endswith(_INTERRUPT_WAITING_FOR_MODEL_SUFFIX) - ) - _MAX_ACP_RESOURCE_BYTES = 512 * 1024 _TEXT_RESOURCE_MIME_PREFIXES = ("text/",) _TEXT_RESOURCE_MIME_TYPES = { @@ -1529,8 +1515,12 @@ class HermesACPAgent(acp.Agent): final_response = result.get("final_response", "") cancelled = bool(state.cancel_event and state.cancel_event.is_set()) interrupted = bool(result.get("interrupted")) or cancelled - suppress_interrupt_response = ( - interrupted and _is_interrupt_waiting_for_model_response(final_response) + # Hermes' local "waiting for model response" interrupt status is metadata, + # not assistant prose — clients get cancellation from stop_reason instead. + from agent.conversation_loop import INTERRUPT_WAITING_FOR_MODEL_PREFIX + + suppress_interrupt_response = interrupted and final_response.startswith( + INTERRUPT_WAITING_FOR_MODEL_PREFIX ) if final_response and not suppress_interrupt_response: try: diff --git a/agent/conversation_loop.py b/agent/conversation_loop.py index 36f35a45a0f..c00bf81a6c8 100644 --- a/agent/conversation_loop.py +++ b/agent/conversation_loop.py @@ -64,6 +64,11 @@ from utils import base_url_host_matches, env_var_enabled logger = logging.getLogger(__name__) +# Stable prefix of the local interrupt status string emitted when a turn is +# cancelled while waiting on the provider. Surfaces (ACP, TUI) match on this +# to treat it as cancellation metadata rather than assistant prose. +INTERRUPT_WAITING_FOR_MODEL_PREFIX = "Operation interrupted: waiting for model response (" + def _ollama_context_limit_error(agent: Any, request_tokens: int) -> Optional[str]: """Return a user-facing error when Ollama is loaded with too little context.""" @@ -1738,7 +1743,7 @@ def run_conversation( agent._vprint(f"{agent.log_prefix}⚡ Interrupted during API call.", force=True) agent._persist_session(messages, conversation_history) interrupted = True - final_response = f"Operation interrupted: waiting for model response ({api_elapsed:.1f}s elapsed)." + final_response = f"{INTERRUPT_WAITING_FOR_MODEL_PREFIX}{api_elapsed:.1f}s elapsed)." break except Exception as api_error: diff --git a/scripts/release.py b/scripts/release.py index 312e53f8c22..9e0f2d07813 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -65,6 +65,7 @@ AUTHOR_MAP = { "290859878+synapsesx@users.noreply.github.com": "synapsesx", "dirtyren@users.noreply.github.com": "dirtyren", "islam666@users.noreply.github.com": "islam666", + "25539605+lsaether@users.noreply.github.com": "lsaether", "zhaolei.vc@bytedance.com": "zhaoleibd", "jeffrobodie@gmail.com": "jeffrobodie-glitch", "kyssta-exe@users.noreply.github.com": "kyssta-exe",