diff --git a/backend/app/services/autonomous_conversation_controller.py b/backend/app/services/autonomous_conversation_controller.py index 8bab940b..5c66aa53 100755 --- a/backend/app/services/autonomous_conversation_controller.py +++ b/backend/app/services/autonomous_conversation_controller.py @@ -32,7 +32,7 @@ class AutonomousConversationController: # Timing configuration self.min_delay_between_actions = 3 # seconds self.max_delay_between_actions = 10 # seconds - self.response_timeout = 30 # seconds + self.response_timeout = 120 # seconds (LLM calls can be slow in production) # Edge case tracking self.consecutive_silence_count = 0 @@ -670,18 +670,25 @@ class AutonomousConversationController: messages = await FocusGroup.get_messages(self.focus_group_id) recent_messages = messages[-20:] if len(messages) > 20 else messages - # Generate response + # Generate response with timeout to prevent infinite hang try: - response_text = await generate_persona_response( - persona=persona, - current_topic=topic, - previous_messages=recent_messages, - temperature=0.7, - focus_group_id=self.focus_group_id, - llm_model=llm_model, - reasoning_effort=reasoning_effort, - verbosity=verbosity + response_text = await asyncio.wait_for( + generate_persona_response( + persona=persona, + current_topic=topic, + previous_messages=recent_messages, + temperature=0.7, + focus_group_id=self.focus_group_id, + llm_model=llm_model, + reasoning_effort=reasoning_effort, + verbosity=verbosity + ), + timeout=self.response_timeout ) + except asyncio.TimeoutError: + error_msg = f"Participant response generation timed out after {self.response_timeout}s" + self.logger.error(f"⏱️ {error_msg}") + return {"error": error_msg} except Exception as e: self.logger.error(f"Error in generate_persona_response: {str(e)}") import traceback diff --git a/backend/app/services/conversation_decision_service.py b/backend/app/services/conversation_decision_service.py index 11e9983e..3fc3daac 100755 --- a/backend/app/services/conversation_decision_service.py +++ b/backend/app/services/conversation_decision_service.py @@ -4,6 +4,7 @@ Uses LLM to make intelligent decisions about conversation flow, participant sele """ from typing import Dict, Any, Optional, List +import asyncio import json from app.services.llm_service import LLMService, LLMServiceError from app.services.conversation_context_service import ConversationContextService @@ -58,12 +59,15 @@ class ConversationDecisionService: focus_group = await FocusGroup.find_by_id(focus_group_id) llm_model = focus_group.get('llm_model') if focus_group else None - # Get LLM decision + # Get LLM decision with timeout to prevent infinite hang try: - response = await LLMService.generate_content( - prompt=prompt, - temperature=temperature, - model_name=llm_model + response = await asyncio.wait_for( + LLMService.generate_content( + prompt=prompt, + temperature=temperature, + model_name=llm_model + ), + timeout=60 ) # Parse the JSON response @@ -92,6 +96,9 @@ class ConversationDecisionService: return decision + except asyncio.TimeoutError: + print(f"⏱️ LLM decision timed out after 60s") + raise ConversationDecisionError("LLM decision timed out after 60s") except LLMServiceError as e: print(f"❌ LLM Service Error: {str(e)}") raise ConversationDecisionError(f"Error getting LLM decision: {str(e)}")