diff --git a/backend/app/services/llm_service.py b/backend/app/services/llm_service.py index 1dcf6a54..b6fb9d51 100755 --- a/backend/app/services/llm_service.py +++ b/backend/app/services/llm_service.py @@ -17,43 +17,29 @@ from typing import Dict, Any, Optional, Union, List from PIL import Image import io -# Set up the Gemini API key (client created lazily to avoid event loop issues) +# Set up API keys GEMINI_API_KEY = os.environ.get('GEMINI_API_KEY', 'AIzaSyAc50jzC3k9K1PmKT1vGFi0sCdhhnqsvl0') -_gemini_client = None -_gemini_client_loop = None - -# Set up OpenAI API key (client created lazily to avoid event loop issues) OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY', 'REDACTED_OPENAI_KEY') -_openai_client = None -_openai_client_loop = None def get_gemini_client(): - """Get or create the Gemini client for the current event loop. + """Create a fresh Gemini client for each call. - Recreates the client if the event loop has changed to avoid - 'Future attached to a different loop' errors in ASGI environments. + Creating a new client per call avoids event loop mismatch issues that occur + when caching clients in ASGI environments where requests may come on different + event loops. The overhead is minimal compared to the LLM API call. """ - global _gemini_client, _gemini_client_loop - current_loop = asyncio.get_running_loop() - if _gemini_client is None or _gemini_client_loop is not current_loop: - _gemini_client = genai.Client(api_key=GEMINI_API_KEY) - _gemini_client_loop = current_loop - return _gemini_client + return genai.Client(api_key=GEMINI_API_KEY) def get_openai_client(): - """Get or create the OpenAI client for the current event loop. + """Create a fresh OpenAI client for each call. - Recreates the client if the event loop has changed to avoid - 'Future attached to a different loop' errors in ASGI environments. + Creating a new client per call avoids event loop mismatch issues that occur + when caching clients in ASGI environments where requests may come on different + event loops. The overhead is minimal compared to the LLM API call. """ - global _openai_client, _openai_client_loop - current_loop = asyncio.get_running_loop() - if _openai_client is None or _openai_client_loop is not current_loop: - _openai_client = AsyncOpenAI(api_key=OPENAI_API_KEY, timeout=600.0) - _openai_client_loop = current_loop - return _openai_client + return AsyncOpenAI(api_key=OPENAI_API_KEY, timeout=600.0) # The default model we're using DEFAULT_MODEL = "gemini-3-pro-preview"