From 5a711f32b13eea8e2d3fa4698f7574fc3434db1c Mon Sep 17 00:00:00 2001 From: teknium1 Date: Sat, 7 Mar 2026 09:19:07 -0800 Subject: [PATCH] fix: enhance payload and context compression handling Added logic to manage multiple compression attempts for large payloads and context length errors. Introduced limits on compression attempts to prevent infinite retries, with appropriate logging and error handling. This ensures better resilience and user feedback when facing compression issues during API calls. --- run_agent.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/run_agent.py b/run_agent.py index ec9caea38..dc6eb7e1a 100644 --- a/run_agent.py +++ b/run_agent.py @@ -3142,10 +3142,13 @@ class AIAgent: api_start_time = time.time() retry_count = 0 max_retries = 6 # Increased to allow longer backoff periods + compression_attempts = 0 + max_compression_attempts = 3 codex_auth_retry_attempted = False nous_auth_retry_attempted = False finish_reason = "stop" + response = None # Guard against UnboundLocalError if all retries fail while retry_count < max_retries: try: @@ -3441,7 +3444,19 @@ class AIAgent: ) if is_payload_too_large: - print(f"{self.log_prefix}⚠️ Request payload too large (413) - attempting compression...") + compression_attempts += 1 + if compression_attempts > max_compression_attempts: + print(f"{self.log_prefix}❌ Max compression attempts ({max_compression_attempts}) reached for payload-too-large error.") + logging.error(f"{self.log_prefix}413 compression failed after {max_compression_attempts} attempts.") + self._persist_session(messages, conversation_history) + return { + "messages": messages, + "completed": False, + "api_calls": api_call_count, + "error": f"Request payload too large: max compression attempts ({max_compression_attempts}) reached.", + "partial": True + } + print(f"{self.log_prefix}⚠️ Request payload too large (413) — compression attempt {compression_attempts}/{max_compression_attempts}...") original_len = len(messages) messages, active_system_prompt = self._compress_context( @@ -3450,6 +3465,7 @@ class AIAgent: if len(messages) < original_len: print(f"{self.log_prefix} 🗜️ Compressed {original_len} → {len(messages)} messages, retrying...") + time.sleep(2) # Brief pause between compression retries continue # Retry with compressed messages else: print(f"{self.log_prefix}❌ Payload too large and cannot compress further.") @@ -3495,6 +3511,20 @@ class AIAgent: else: print(f"{self.log_prefix}⚠️ Context length exceeded at minimum tier — attempting compression...") + compression_attempts += 1 + if compression_attempts > max_compression_attempts: + print(f"{self.log_prefix}❌ Max compression attempts ({max_compression_attempts}) reached.") + logging.error(f"{self.log_prefix}Context compression failed after {max_compression_attempts} attempts.") + self._persist_session(messages, conversation_history) + return { + "messages": messages, + "completed": False, + "api_calls": api_call_count, + "error": f"Context length exceeded: max compression attempts ({max_compression_attempts}) reached.", + "partial": True + } + print(f"{self.log_prefix} 🗜️ Context compression attempt {compression_attempts}/{max_compression_attempts}...") + original_len = len(messages) messages, active_system_prompt = self._compress_context( messages, system_message, approx_tokens=approx_tokens @@ -3503,6 +3533,7 @@ class AIAgent: if len(messages) < original_len or new_ctx and new_ctx < old_ctx: if len(messages) < original_len: print(f"{self.log_prefix} 🗜️ Compressed {original_len} → {len(messages)} messages, retrying...") + time.sleep(2) # Brief pause between compression retries continue # Retry with compressed messages or new tier else: # Can't compress further and already at minimum tier @@ -3581,6 +3612,14 @@ class AIAgent: if interrupted: break + # Guard: if all retries exhausted without a successful response + # (e.g. repeated context-length errors that exhausted retry_count), + # the `response` variable is still None. Break out cleanly. + if response is None: + print(f"{self.log_prefix}❌ All API retries exhausted with no successful response.") + self._persist_session(messages, conversation_history) + break + try: if self.api_mode == "codex_responses": assistant_message, finish_reason = self._normalize_codex_response(response)