diff --git a/agent/conversation_loop.py b/agent/conversation_loop.py index ef69ac68329..163a508a8cd 100644 --- a/agent/conversation_loop.py +++ b/agent/conversation_loop.py @@ -3197,15 +3197,22 @@ def run_conversation( # Terminal — flush buffered context so the user sees # what was tried before the abort. agent._flush_status_buffer() + # Summarize once: Cloudflare/proxy HTML challenge pages and + # other raw provider bodies must be collapsed to a short + # one-liner here, otherwise the full page leaks into the + # returned ``error`` field and downstream consumers deliver + # it verbatim (e.g. a cron failure notification dumped a + # ~60KB Cloudflare challenge page as 31 Discord messages). + _nonretryable_summary = agent._summarize_api_error(api_error) if classified.reason == FailoverReason.content_policy_blocked: agent._emit_status( f"❌ Provider safety filter blocked this request: " - f"{agent._summarize_api_error(api_error)}" + f"{_nonretryable_summary}" ) else: agent._emit_status( f"❌ Non-retryable error (HTTP {status_code}): " - f"{agent._summarize_api_error(api_error)}" + f"{_nonretryable_summary}" ) agent._vprint(f"{agent.log_prefix}❌ Non-retryable client error (HTTP {status_code}). Aborting.", force=True) agent._vprint(f"{agent.log_prefix} 🔌 Provider: {_provider} Model: {_model}", force=True) @@ -3309,7 +3316,7 @@ def run_conversation( "api_calls": api_call_count, "completed": False, "failed": True, - "error": str(api_error), + "error": _nonretryable_summary, } if retry_count >= max_retries: