From f33cd0513836105a83825713f64dc88174f6fb7b Mon Sep 17 00:00:00 2001 From: Ricardo-M-L Date: Thu, 9 Apr 2026 00:30:56 +0800 Subject: [PATCH] fix: prevent needless retry of TokenLimitExceeded and fix search engine fallback Bug 1: The retry decorator on ask(), ask_with_images(), and ask_tool() included `Exception` in retry_if_exception_type alongside `OpenAIError` and `ValueError`. Since `TokenLimitExceeded` inherits from `Exception`, it was retried 6 times despite the comment saying otherwise. Removed `Exception` from the filter. Bug 2: In _try_all_engines(), the call to _perform_search_with_engine() was not wrapped in try/except. If an engine raised an exception, remaining fallback engines were never tried. Added try/except to log the warning and continue to the next engine. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/llm.py | 6 +++--- app/tool/web_search.py | 14 +++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/llm.py b/app/llm.py index 82ebe8857..80d60a39d 100644 --- a/app/llm.py +++ b/app/llm.py @@ -355,7 +355,7 @@ def format_messages( wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6), retry=retry_if_exception_type( - (OpenAIError, Exception, ValueError) + (OpenAIError, ValueError) ), # Don't retry TokenLimitExceeded ) async def ask( @@ -482,7 +482,7 @@ async def ask( wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6), retry=retry_if_exception_type( - (OpenAIError, Exception, ValueError) + (OpenAIError, ValueError) ), # Don't retry TokenLimitExceeded ) async def ask_with_images( @@ -638,7 +638,7 @@ async def ask_with_images( wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6), retry=retry_if_exception_type( - (OpenAIError, Exception, ValueError) + (OpenAIError, ValueError) ), # Don't retry TokenLimitExceeded ) async def ask_tool( diff --git a/app/tool/web_search.py b/app/tool/web_search.py index b9b9e31ae..85ca3d70e 100644 --- a/app/tool/web_search.py +++ b/app/tool/web_search.py @@ -297,11 +297,19 @@ async def _try_all_engines( for engine_name in engine_order: engine = self._search_engine[engine_name] logger.info(f"🔎 Attempting search with {engine_name.capitalize()}...") - search_items = await self._perform_search_with_engine( - engine, query, num_results, search_params - ) + try: + search_items = await self._perform_search_with_engine( + engine, query, num_results, search_params + ) + except Exception as e: + logger.warning( + f"Search engine {engine_name.capitalize()} raised an exception: {e}" + ) + failed_engines.append(engine_name) + continue if not search_items: + failed_engines.append(engine_name) continue if failed_engines: