@@ -108,11 +108,13 @@ def __init__(
108108 # Form state
109109 self .form_fields : Dict [str , Any ] = {}
110110 self .collected_data : Dict [str , str ] = {}
111- self .questions : list [FormQuestion ] = []
111+ # Pre-initialize questions so conversation can start immediately
112+ self .questions : list [FormQuestion ] = self ._create_questions_from_analysis ({})
112113 self .current_question_index = 0
113114
114115 # Browser initialization
115116 self .browser_init_task = None
117+ self .browser_initializing = False
116118
117119 # Enhanced prompt for form filling
118120 enhanced_prompt = system_prompt + """
@@ -137,6 +139,12 @@ def __init__(
137139
138140 async def _initialize_browser (self ):
139141 """Initialize browser and extract form fields"""
142+ # Prevent multiple initializations
143+ if self .browser_initializing or self .stagehand_filler :
144+ logger .info ("🔒 Browser already initializing or initialized, skipping" )
145+ return
146+
147+ self .browser_initializing = True
140148 try :
141149 logger .info ("🌐 Initializing browser and analyzing form" )
142150 self .stagehand_filler = StagehandFormFiller (
@@ -159,14 +167,15 @@ async def _initialize_browser(self):
159167 except Exception as e :
160168 logger .warning (f"Could not extract form fields: { e } " )
161169
162- # Always create questions - don't depend on form extraction
163- self .questions = self ._create_questions_from_analysis ({})
164-
165- logger .info (f"✅ Browser ready with { len (self .questions )} questions" )
170+ # Questions already initialized in __init__, no need to recreate
171+ logger .info (f"✅ Browser ready, form can now be filled" )
166172
167173 except Exception as e :
168174 logger .error (f"❌ Failed to initialize browser: { e } " )
175+ self .browser_initializing = False
169176 raise
177+ finally :
178+ self .browser_initializing = False
170179
171180 def _create_questions_from_analysis (self , form_analysis : Dict [str , Any ]) -> list [FormQuestion ]:
172181 """Create questions based on form analysis"""
@@ -241,19 +250,12 @@ def _create_questions_from_analysis(self, form_analysis: Dict[str, Any]) -> list
241250 async def _fill_form_field_async (self , field_name : str , value : str ):
242251 """Fill a form field asynchronously in background (non-blocking)"""
243252 try :
244- await self ._fill_form_field (field_name , value )
245- except Exception as e :
246- logger .error (f"❌ Background form filling error for { field_name } : { e } " )
247-
248- async def _fill_form_field (self , field_name : str , value : str ):
249- """Fill a form field in the browser in real-time"""
250- if not self .stagehand_filler :
251- logger .warning ("⚠️ Browser not initialized yet" )
252- return
253-
254- try :
253+ # Wait for browser initialization if needed
254+ if self .browser_init_task :
255+ logger .info (f"⏳ Waiting for browser to initialize before filling { field_name } " )
256+ await self .browser_init_task
257+
255258 logger .info (f"🖊️ Filling field '{ field_name } ' with: { value } in background" )
256-
257259 # Use StagehandFormFiller's fill_field method which handles the mapping
258260 success = await self .stagehand_filler .fill_field (field_name , value )
259261
@@ -264,10 +266,15 @@ async def _fill_form_field(self, field_name: str, value: str):
264266
265267 except Exception as e :
266268 logger .error (f"Error filling field { field_name } : { e } " )
267- raise # Re-raise so background task can catch it
268-
269+ raise # Re-raise so background task can catch it
270+
269271 async def _submit_form (self ):
270272 """Submit the completed form"""
273+ # Wait for browser initialization if needed
274+ if self .browser_init_task and not self .stagehand_filler :
275+ logger .info ("⏳ Waiting for browser to initialize before submitting form" )
276+ await self .browser_init_task
277+
271278 if not self .stagehand_filler :
272279 return False
273280
@@ -309,12 +316,10 @@ async def process_context(
309316 AgentResponse: Text responses to the user
310317 EndCall: Call termination when form is complete
311318 """
312- # Initialize browser on first call
313- if not self .browser_init_task :
319+ # Initialize browser on first call (non-blocking)
320+ if not self .browser_init_task and not self . stagehand_filler :
314321 self .browser_init_task = asyncio .create_task (self ._initialize_browser ())
315- # Wait for initialization to complete
316- await self .browser_init_task
317- logger .info (f"📝 Initialization complete. Questions loaded: { len (self .questions )} " )
322+ logger .info ("🚀 Browser initialization started in background" )
318323
319324 # Get current question after initialization
320325 current_question = self .get_current_question ()
@@ -388,7 +393,6 @@ async def process_context(
388393 Then acknowledge their answer naturally.
389394 """
390395
391- # Enhanced config
392396 enhanced_config = gemini_types .GenerateContentConfig (
393397 system_instruction = self .generation_config .system_instruction + question_context ,
394398 temperature = self .temperature ,
@@ -427,13 +431,10 @@ async def process_context(
427431
428432 # Store data first
429433 self .collected_data [field_name ] = value
430-
431434 # Fill the form field asynchronously in background (non-blocking)
432435 asyncio .create_task (self ._fill_form_field_async (field_name , value ))
433-
434436 # Log the collected data
435437 logger .info (f"📊 Collected: { field_name } ={ value } " )
436-
437438 # Move to next question immediately (don't wait for form filling)
438439 self .current_question_index += 1
439440 field_recorded = True
0 commit comments