wuhp commited on
Commit
53d7d01
Β·
verified Β·
1 Parent(s): 373e394

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -109
app.py CHANGED
@@ -157,8 +157,11 @@ def configure_gemini(api_key: str | None, model_name: str | None) -> str:
157
  def call_gemini(prompt: str, api_key: str, model_name: str, use_grounding: bool = False) -> str:
158
  """Calls the Gemini API with a given prompt, optionally using grounding."""
159
  # This check is crucial - it will raise an error *before* the API call if prereqs aren't met
160
- if not api_key or not model_name: # Check for empty string "" as well as None
161
- raise ValueError("Gemini API key or model not set.")
 
 
 
162
  try:
163
  genai.configure(api_key=api_key)
164
  model = genai.GenerativeModel(model_name)
@@ -236,9 +239,9 @@ def check_send_button_ready(profile: gr.OAuthProfile | None, token: gr.OAuthToke
236
  print(f" Received token type: {type(token)}, is None: {token is None}")
237
  # For api_key, print part of the key if not None for verification, be careful with full key
238
  # Also check for empty string for printing
239
- api_key_display = api_key[:5] if api_key else ('Empty String' if isinstance(api_key, str) and api_key == "" else 'N/A')
240
- print(f" Received api_key is None: {api_key is None}, is Empty String: {api_key == '' if isinstance(api_key, str) else 'N/A'}, first 5 chars or status: {api_key_display}")
241
- print(f" Received model_name: {model_name}")
242
  # --- END ENHANCED DEBUGGING LOGS ---
243
 
244
  is_logged_in = profile is not None and token is not None
@@ -265,11 +268,9 @@ def ai_workflow_chat(
265
  history: list[dict],
266
  hf_profile: gr.OAuthProfile | None,
267
  hf_token: gr.OAuthToken | None,
268
- # gemini_api_key and gemini_model are inputs, but their *state* is managed by change handlers,
269
- # so we don't yield them back in this version. They are read from the state at the start
270
- # of the function call.
271
- gemini_api_key: str | None, # Read key from state
272
- gemini_model: str | None, # Read model from state
273
  repo_id_state: str | None,
274
  workflow_state: str,
275
  space_sdk: str,
@@ -297,7 +298,8 @@ def ai_workflow_chat(
297
  str | None, # 8: Updated repo name (for repo_name_state state)
298
  str | None, # 9: Updated generated code (for generated_code_state state)
299
  bool, # 10: Updated use_grounding_state (for use_grounding_state state)
300
- # gemini_key, gemini_model removed from outputs based on new key handling strategy
 
301
  ]:
302
  """
303
  Generator function to handle the AI workflow state machine.
@@ -328,9 +330,10 @@ def ai_workflow_chat(
328
  # Yield immediately to update the chat UI with the user's message
329
  # This provides immediate feedback to the user while the AI processes
330
  # Ensure all state variables and UI outputs are yielded back in the correct order
331
- # NOTE: gemini_key and gemini_model are NOT yielded back
332
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
333
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
334
 
335
  try:
336
  # --- State Machine Logic based on the current 'state' variable ---
@@ -339,17 +342,17 @@ def ai_workflow_chat(
339
  # the checks remain as a safeguard for the workflow logic itself.
340
  if not (hf_profile and hf_token):
341
  history = add_bot_message(history, "Workflow paused: Please log in to Hugging Face first.")
342
- # NOTE: gemini_key and gemini_model are NOT yielded back
343
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
344
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
345
  return # Stop workflow execution for this click
346
 
347
  # Check if API key is non-empty string and model is set
348
  if not (isinstance(gemini_api_key, str) and gemini_api_key != "" and gemini_model):
349
  history = add_bot_message(history, "Workflow cannot start: Please ensure your Gemini API key is entered and a model is selected.")
350
- # NOTE: gemini_key and gemini_model are NOT yielded back
351
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
352
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
353
  return # Stop workflow execution for this click
354
 
355
 
@@ -366,9 +369,10 @@ def ai_workflow_chat(
366
  history = add_bot_message(history, "Workflow reset.")
367
  # Yield updated history and reset state variables to their initial values
368
  # Also reset UI outputs to their initial state
369
- # NOTE: gemini_key and gemini_model are NOT yielded back (they are managed by change handlers)
370
  yield (history, None, STATE_IDLE, "<p>No Space created yet.</p>", "", "", 0,
371
- None, None, None, False) # Reset use_grounding to default False, and other states to None/default
 
372
  # No return needed after yield in this generator pattern; execution for this click ends here.
373
 
374
  elif generate_match:
@@ -381,9 +385,9 @@ def ai_workflow_chat(
381
  repo_name = new_repo_name
382
  app_desc = new_app_desc
383
  # Yield updated history and state variables (pass UI outputs through)
384
- # NOTE: gemini_key and gemini_model are NOT yielded back
385
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
386
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
387
  # No return needed
388
 
389
  elif create_match:
@@ -393,9 +397,9 @@ def ai_workflow_chat(
393
  state = STATE_CREATING_SPACE # Transition state to creation
394
  repo_name = new_repo_name # Store the validated repo name
395
  # Yield updated history and state variables (pass UI outputs through)
396
- # NOTE: gemini_key and gemini_model are NOT yielded back
397
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
398
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
399
  # No return needed
400
 
401
  elif "create" in message.lower() and not repo_id:
@@ -403,18 +407,18 @@ def ai_workflow_chat(
403
  history = add_bot_message(history, "Okay, what should the Space be called? (e.g., `my-awesome-app`)")
404
  state = STATE_AWAITING_REPO_NAME # Transition to the state where we wait for the name
405
  # Yield updated history and state (pass UI outputs through)
406
- # NOTE: gemini_key and gemini_model are NOT yielded back
407
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
408
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
409
  # No return needed
410
 
411
  else:
412
  # Command not recognized in IDLE state
413
  history = add_bot_message(history, "Command not recognized. Try 'generate me a gradio app called myapp', or 'reset'.")
414
  # Yield updated history and current state (pass UI outputs through)
415
- # NOTE: gemini_key and gemini_model are NOT yielded back
416
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
417
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
418
  # No return needed
419
 
420
 
@@ -426,9 +430,9 @@ def ai_workflow_chat(
426
  if not new_repo_name or re.search(r'[^a-zA-Z0-9_-]', new_repo_name) or len(new_repo_name) > 100:
427
  history = add_bot_message(history, "Invalid name. Please provide a single word/slug for the Space name (letters, numbers, underscores, hyphens only, max 100 chars).")
428
  # Stay in AWAITING_REPO_NAME state and yield message (pass UI outputs through)
429
- # NOTE: gemini_key and gemini_model are NOT yielded back
430
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
431
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
432
  # No return needed
433
 
434
  else:
@@ -437,9 +441,9 @@ def ai_workflow_chat(
437
  repo_name = new_repo_name # Store the validated repo name
438
  # Yield updated history, state, and repo name. UI outputs remain unchanged for now.
439
  # The next click will proceed from the STATE_CREATING_SPACE block.
440
- # NOTE: gemini_key and gemini_model are NOT yielded back
441
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
442
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
443
  # No return needed
444
 
445
  # Note: Each 'elif' block below represents a distinct step in the workflow triggered
@@ -450,9 +454,9 @@ def ai_workflow_chat(
450
  if not repo_name:
451
  history = add_bot_message(history, "Internal error: Repo name missing for creation. Resetting.")
452
  # Reset relevant states and UI outputs on critical error
453
- # NOTE: gemini_key and gemini_model are NOT yielded back
454
  yield (history, None, STATE_IDLE, "<p>Error creating space.</p>", "", "", 0,
455
- None, None, None, use_grounding) # Pass grounding state through
 
456
  # No return needed
457
 
458
  else:
@@ -464,17 +468,17 @@ def ai_workflow_chat(
464
  history = add_bot_message(history, f"βœ… Space `{repo_id}` created. Click 'Send' to generate and upload code.")
465
  state = STATE_GENERATING_CODE # Transition to the next state
466
  # Yield updated state variables and history, and the new iframe HTML
467
- # NOTE: gemini_key and gemini_model are NOT yielded back
468
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
469
- attempts, app_desc, repo_name, generated_code, use_grounding) # Pass logs and grounding through
 
470
  # No return needed
471
 
472
  except Exception as e:
473
  history = add_bot_message(history, f"❌ Error creating space: {e}. Click 'reset'.")
474
  # Yield error message and reset state on failure
475
- # NOTE: gemini_key and gemini_model are NOT yielded back
476
  yield (history, None, STATE_IDLE, "<p>Error creating space.</p>", "", "", 0,
477
- None, None, None, use_grounding) # Pass logs and grounding through
 
478
  # No return needed
479
 
480
 
@@ -493,9 +497,9 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
493
  if use_grounding:
494
  history = add_bot_message(history, "(Using Grounding with Google Search)")
495
  # Yield to show message before the potentially time-consuming API call
496
- # NOTE: gemini_key and gemini_model are NOT yielded back
497
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
498
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
499
 
500
  # Perform the Gemini API call to generate code, optionally using grounding
501
  # Use the gemini_api_key and gemini_model inputs directly (which come from state)
@@ -516,17 +520,17 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
516
  state = STATE_UPLOADING_APP_PY # Transition to the upload state
517
  generated_code = code # Store the generated code in the state variable for the next step
518
  # Yield updated state variables and history (pass UI outputs and other states through)
519
- # NOTE: gemini_key and gemini_model are NOT yielded back
520
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
521
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
522
  # No return needed
523
 
524
  except Exception as e:
525
  history = add_bot_message(history, f"❌ Error generating code: {e}. Click 'reset'.")
526
  # Yield error message and reset state on failure
527
- # NOTE: gemini_key and gemini_model are NOT yielded back
528
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
529
- None, None, None, use_grounding)
 
530
  # No return needed
531
 
532
 
@@ -535,17 +539,17 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
535
  code_to_upload = generated_code
536
  if not code_to_upload:
537
  history = add_bot_message(history, "Internal error: No code to upload. Resetting.")
538
- # NOTE: gemini_key and gemini_model are NOT yielded back
539
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
540
- None, None, None, use_grounding)
 
541
  # No return needed
542
 
543
  else:
544
  history = add_bot_message(history, "☁️ Uploading `app.py`...")
545
  # Yield to show message before the upload action (pass UI outputs and states through)
546
- # NOTE: gemini_key and gemini_model are NOT yielded back
547
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
548
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
549
 
550
  try:
551
  # Perform the file upload action
@@ -554,26 +558,26 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
554
  state = STATE_GENERATING_REQUIREMENTS # Transition state
555
  generated_code = None # Clear the stored code after use to free memory/state space
556
  # Yield updated state variables and history (pass UI outputs and other states through)
557
- # NOTE: gemini_key and gemini_model are NOT yielded back
558
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
559
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
560
  # No return needed
561
 
562
  except Exception as e:
563
  history = add_bot_message(history, f"❌ Error uploading `app.py`: {e}. Click 'reset'.")
564
  # Yield error message and reset state on failure
565
- # NOTE: gemini_key and gemini_model are NOT yielded back
566
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
567
- None, None, None, use_grounding)
 
568
  # No return needed
569
 
570
 
571
  elif state == STATE_GENERATING_REQUIREMENTS:
572
  history = add_bot_message(history, "πŸ“„ Generating `requirements.txt`...")
573
  # Yield to show message before generating requirements (pass UI outputs and states through)
574
- # NOTE: gemini_key and gemini_model are NOT yielded back
575
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
576
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
577
 
578
  # Logic to determine required packages based on SDK and keywords in the app description
579
  reqs_list = ["gradio"] if space_sdk == "gradio" else ["streamlit"]
@@ -614,9 +618,9 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
614
  state = STATE_UPLOADING_REQUIREMENTS # Transition state
615
  generated_code = reqs_content # Store requirements content
616
  # Yield updated state variables and history (pass UI outputs and other states through)
617
- # NOTE: gemini_key and gemini_model are NOT yielded back
618
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
619
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
620
  # No return needed
621
 
622
 
@@ -625,17 +629,17 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
625
  reqs_content_to_upload = generated_code
626
  if not reqs_content_to_upload:
627
  history = add_bot_message(history, "Internal error: No requirements content to upload. Resetting.")
628
- # NOTE: gemini_key and gemini_model are NOT yielded back
629
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
630
- None, None, None, use_grounding)
 
631
  # No return needed
632
 
633
  else:
634
  history = add_bot_message(history, "☁️ Uploading `requirements.txt`...")
635
  # Yield message before upload (pass UI outputs and states through)
636
- # NOTE: gemini_key and gemini_model are NOT yielded back
637
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
638
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
639
 
640
  try:
641
  # Perform requirements file upload
@@ -644,25 +648,25 @@ Return **only** the python code block for `app.py`. Do not include any extra tex
644
  state = STATE_GENERATING_README # Transition state
645
  generated_code = None # Clear content after use
646
  # Yield updated state variables and history (pass UI outputs and other states through)
647
- # NOTE: gemini_key and gemini_model are NOT yielded back
648
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
649
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
650
  # No return needed
651
 
652
  except Exception as e:
653
  history = add_bot_message(history, f"❌ Error uploading `requirements.txt`: {e}. Click 'reset'.")
654
  # Yield error message and reset state on failure
655
- # NOTE: gemini_key and gemini_model are NOT yielded back
656
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
657
- None, None, None, use_grounding)
 
658
  # No return needed
659
 
660
  elif state == STATE_GENERATING_README:
661
  history = add_bot_message(history, "πŸ“ Generating `README.md`...")
662
  # Yield message before generating README (pass UI outputs and states through)
663
- # NOTE: gemini_key and gemini_model are NOT yielded back
664
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
665
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
666
 
667
  # Generate simple README content with Space metadata header
668
  readme_title = repo_name if repo_name else "My Awesome Space"
@@ -689,9 +693,9 @@ This Space was automatically generated by an AI workflow using Google Gemini and
689
  state = STATE_UPLOADING_README # Transition state
690
  generated_code = readme_content # Store README content
691
  # Yield updated state variables and history (pass UI outputs and other states through)
692
- # NOTE: gemini_key and gemini_model are NOT yielded back
693
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
694
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
695
  # No return needed
696
 
697
 
@@ -700,17 +704,17 @@ This Space was automatically generated by an AI workflow using Google Gemini and
700
  readme_content_to_upload = generated_code
701
  if not readme_content_to_upload:
702
  history = add_bot_message(history, "Internal error: No README content to upload. Resetting.")
703
- # NOTE: gemini_key and gemini_model are NOT yielded back
704
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
705
- None, None, None, use_grounding)
 
706
  # No return needed
707
 
708
  else:
709
  history = add_bot_message(history, "☁️ Uploading `README.md`...")
710
  # Yield message before upload (pass UI outputs and states through)
711
- # NOTE: gemini_key and gemini_model are NOT yielded back
712
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
713
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
714
 
715
  try:
716
  # Perform README file upload
@@ -719,25 +723,25 @@ This Space was automatically generated by an AI workflow using Google Gemini and
719
  state = STATE_CHECKING_LOGS_BUILD # Transition to checking build logs
720
  generated_code = None # Clear content after use
721
  # Yield updated state variables and history (pass UI outputs and other states through)
722
- # NOTE: gemini_key and gemini_model are NOT yielded back
723
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
724
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
725
  # No return needed
726
 
727
  except Exception as e:
728
  history = add_bot_message(history, f"❌ Error uploading `README.md`: {e}. Click 'reset'.")
729
  # Yield error message and reset state on failure
730
- # NOTE: gemini_key and gemini_model are NOT yielded back
731
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
732
- None, None, None, use_grounding)
 
733
  # No return needed
734
 
735
  elif state == STATE_CHECKING_LOGS_BUILD:
736
  history = add_bot_message(history, "πŸ” Fetching build logs...")
737
  # Yield message before fetching logs (which includes a delay) (pass UI outputs and states through)
738
- # NOTE: gemini_key and gemini_model are NOT yielded back
739
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
740
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
741
 
742
  # Fetch build logs from HF Space
743
  build_logs_text = get_build_logs_action(repo_id, hf_profile, hf_token)
@@ -748,27 +752,27 @@ This Space was automatically generated by an AI workflow using Google Gemini and
748
  history = add_bot_message(history, "⚠️ Build logs indicate potential issues. Please inspect above. Click 'Send' to check container logs (app might still start despite build warnings).")
749
  state = STATE_CHECKING_LOGS_RUN # Transition even on build error, to see if container starts
750
  # Yield updated state, logs, and variables
751
- # NOTE: gemini_key and gemini_model are NOT yielded back
752
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
753
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
754
  # No return needed
755
 
756
  else:
757
  history = add_bot_message(history, "βœ… Build logs fetched. Click 'Send' to check container logs.")
758
  state = STATE_CHECKING_LOGS_RUN # Transition to next log check
759
  # Yield updated state, logs, and variables
760
- # NOTE: gemini_key and gemini_model are NOT yielded back
761
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
762
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
763
  # No return needed
764
 
765
 
766
  elif state == STATE_CHECKING_LOGS_RUN:
767
  history = add_bot_message(history, "πŸ” Fetching container logs...")
768
  # Yield message before fetching logs (includes a delay) (pass UI outputs and states through)
769
- # NOTE: gemini_key and gemini_model are NOT yielded back
770
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
771
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
772
 
773
  # Fetch container logs from HF Space
774
  container_logs_text = get_container_logs_action(repo_id, hf_profile, hf_token)
@@ -780,9 +784,9 @@ This Space was automatically generated by an AI workflow using Google Gemini and
780
  history = add_bot_message(history, f"❌ Errors detected in container logs. Attempting debug fix #{attempts}/{MAX_DEBUG_ATTEMPTS}. Click 'Send' to proceed.")
781
  state = STATE_DEBUGGING_CODE # Transition to the debugging state
782
  # Yield updated state, logs, attempts, and variables
783
- # NOTE: gemini_key and gemini_model are NOT yielded back
784
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
785
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
786
  # No return needed
787
 
788
  elif ("error" in updated_run.lower() or "exception" in updated_run.lower()) and attempts >= MAX_DEBUG_ATTEMPTS:
@@ -790,9 +794,9 @@ This Space was automatically generated by an AI workflow using Google Gemini and
790
  history = add_bot_message(history, f"❌ Errors detected in container logs. Max debug attempts ({MAX_DEBUG_ATTEMPTS}) reached. Please inspect logs manually or click 'reset'.")
791
  state = STATE_COMPLETE # Workflow ends on failure after attempts
792
  # Yield updated state, logs, attempts, and variables
793
- # NOTE: gemini_key and gemini_model are NOT yielded back
794
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
795
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
796
  # No return needed
797
 
798
  else:
@@ -800,9 +804,9 @@ This Space was automatically generated by an AI workflow using Google Gemini and
800
  history = add_bot_message(history, "βœ… App appears to be running successfully! Check the iframe above. Click 'reset' to start a new project.")
801
  state = STATE_COMPLETE # Workflow ends on success
802
  # Yield updated state, logs, attempts, and variables
803
- # NOTE: gemini_key and gemini_model are NOT yielded back
804
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
805
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
806
  # No return needed
807
 
808
 
@@ -811,9 +815,9 @@ This Space was automatically generated by an AI workflow using Google Gemini and
811
  if use_grounding:
812
  history = add_bot_message(history, "(Using Grounding with Google Search)")
813
  # Yield message before Gemini API call (pass UI outputs and states through)
814
- # NOTE: gemini_key and gemini_model are NOT yielded back
815
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
816
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
817
 
818
  # Construct prompt for Gemini including the container logs
819
  debug_prompt = f"""
@@ -848,17 +852,17 @@ Return **only** the python code block for app.py. Do not include any extra text,
848
  state = STATE_UPLOADING_FIXED_APP_PY # Transition to the upload state for the fix
849
  generated_code = fix_code # Store the generated fix code
850
  # Yield updated state, code, and variables (pass UI outputs and states through)
851
- # NOTE: gemini_key and gemini_model are NOT yielded back
852
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
853
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
854
  # No return needed
855
 
856
  except Exception as e:
857
  history = add_bot_message(history, f"❌ Error generating debug code: {e}. Click 'reset'.")
858
  # Yield error message and reset state on failure
859
- # NOTE: gemini_key and gemini_model are NOT yielded back
860
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
861
- None, None, None, use_grounding)
 
862
  # No return needed
863
 
864
  elif state == STATE_UPLOADING_FIXED_APP_PY:
@@ -866,17 +870,17 @@ Return **only** the python code block for app.py. Do not include any extra text,
866
  fixed_code_to_upload = generated_code
867
  if not fixed_code_to_upload:
868
  history = add_bot_message(history, "Internal error: No fixed code available to upload. Resetting.")
869
- # NOTE: gemini_key and gemini_model are NOT yielded back
870
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
871
- None, None, None, use_grounding)
 
872
  # No return needed
873
 
874
  else:
875
  history = add_bot_message(history, "☁️ Uploading fixed `app.py`...")
876
  # Yield message before upload (pass UI outputs and states through)
877
- # NOTE: gemini_key and gemini_model are NOT yielded back
878
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
879
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
880
 
881
  try:
882
  # Perform the upload of the fixed app.py
@@ -885,25 +889,25 @@ Return **only** the python code block for app.py. Do not include any extra text,
885
  state = STATE_CHECKING_LOGS_RUN # Go back to checking run logs after uploading the fix
886
  generated_code = None # Clear code after use
887
  # Yield updated state, code, and variables (pass UI outputs and states through)
888
- # NOTE: gemini_key and gemini_model are NOT yielded back
889
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
890
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
891
  # No return needed
892
 
893
  except Exception as e:
894
  history = add_bot_message(history, f"❌ Error uploading fixed `app.py`: {e}. Click 'reset'.")
895
  # Yield error message and reset state on failure
896
- # NOTE: gemini_key and gemini_model are NOT yielded back
897
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
898
- None, None, None, use_grounding)
 
899
  # No return needed
900
 
901
  elif state == STATE_COMPLETE:
902
  # If in the complete state, the workflow is finished for this project.
903
  # Subsequent clicks just add user messages; we simply yield the current state.
904
- # NOTE: gemini_key and gemini_model are NOT yielded back
905
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
906
- attempts, app_desc, repo_name, generated_code, use_grounding)
 
907
  # No return needed
908
 
909
 
@@ -913,9 +917,9 @@ Return **only** the python code block for app.py. Do not include any extra text,
913
  history = add_bot_message(history, error_message)
914
  print(f"Critical Error in state {state}: {e}") # Log the error for debugging purposes
915
  # Yield an error state and reset essential workflow variables on critical failure
916
- # NOTE: gemini_key and gemini_model are NOT yielded back
917
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
918
- None, None, None, use_grounding) # Include use_grounding
 
919
  # No return needed after yield
920
 
921
 
@@ -1090,8 +1094,9 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
1090
  repo_id, workflow, # Update workflow State variables
1091
  iframe, run_txt, build_txt, # Update UI component outputs
1092
  debug_attempts, app_description, repo_name_state, generated_code_state, # Update other State variables
1093
- use_grounding_state # Update the grounding state output
1094
- # REMOVED: gemini_key, gemini_model from outputs
 
1095
  ]
1096
  ).success( # Chain a .success() event to run *after* the .click() handler completes without error
1097
  # Clear the user input textbox after the message is sent and processed
 
157
  def call_gemini(prompt: str, api_key: str, model_name: str, use_grounding: bool = False) -> str:
158
  """Calls the Gemini API with a given prompt, optionally using grounding."""
159
  # This check is crucial - it will raise an error *before* the API call if prereqs aren't met
160
+ # Check for empty string "" as well as None
161
+ if not isinstance(api_key, str) or api_key == "" or not model_name:
162
+ # This error indicates a failure in the workflow logic or state propagation
163
+ # because this function should only be called when prereqs are met.
164
+ raise ValueError(f"Gemini API call prerequisites not met: api_key={api_key}, model_name={model_name}")
165
  try:
166
  genai.configure(api_key=api_key)
167
  model = genai.GenerativeModel(model_name)
 
239
  print(f" Received token type: {type(token)}, is None: {token is None}")
240
  # For api_key, print part of the key if not None for verification, be careful with full key
241
  # Also check for empty string for printing
242
+ api_key_display = api_key[:5] if isinstance(api_key, str) and api_key else ('Empty String' if isinstance(api_key, str) and api_key == "" else 'None')
243
+ print(f" Received api_key: Type={type(api_key)}, Value={api_key_display}")
244
+ print(f" Received model_name: Type={type(model_name)}, Value={model_name}")
245
  # --- END ENHANCED DEBUGGING LOGS ---
246
 
247
  is_logged_in = profile is not None and token is not None
 
268
  history: list[dict],
269
  hf_profile: gr.OAuthProfile | None,
270
  hf_token: gr.OAuthToken | None,
271
+ # Pass gemini_api_key and gemini_model as inputs - these come from the State variables
272
+ gemini_api_key: str | None,
273
+ gemini_model: str | None,
 
 
274
  repo_id_state: str | None,
275
  workflow_state: str,
276
  space_sdk: str,
 
298
  str | None, # 8: Updated repo name (for repo_name_state state)
299
  str | None, # 9: Updated generated code (for generated_code_state state)
300
  bool, # 10: Updated use_grounding_state (for use_grounding_state state)
301
+ str | None, # 11: Explicitly yield gemini_api_key State
302
+ str | None, # 12: Explicitly yield gemini_model State
303
  ]:
304
  """
305
  Generator function to handle the AI workflow state machine.
 
330
  # Yield immediately to update the chat UI with the user's message
331
  # This provides immediate feedback to the user while the AI processes
332
  # Ensure all state variables and UI outputs are yielded back in the correct order
333
+ # Include gemini_api_key and gemini_model in the yield tuple
334
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
335
+ attempts, app_desc, repo_name, generated_code, use_grounding,
336
+ gemini_api_key, gemini_model) # Explicitly pass back current state values
337
 
338
  try:
339
  # --- State Machine Logic based on the current 'state' variable ---
 
342
  # the checks remain as a safeguard for the workflow logic itself.
343
  if not (hf_profile and hf_token):
344
  history = add_bot_message(history, "Workflow paused: Please log in to Hugging Face first.")
 
345
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
346
+ attempts, app_desc, repo_name, generated_code, use_grounding,
347
+ gemini_api_key, gemini_model) # Explicitly pass back current state values
348
  return # Stop workflow execution for this click
349
 
350
  # Check if API key is non-empty string and model is set
351
  if not (isinstance(gemini_api_key, str) and gemini_api_key != "" and gemini_model):
352
  history = add_bot_message(history, "Workflow cannot start: Please ensure your Gemini API key is entered and a model is selected.")
 
353
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
354
+ attempts, app_desc, repo_name, generated_code, use_grounding,
355
+ gemini_api_key, gemini_model) # Explicitly pass back current state values
356
  return # Stop workflow execution for this click
357
 
358
 
 
369
  history = add_bot_message(history, "Workflow reset.")
370
  # Yield updated history and reset state variables to their initial values
371
  # Also reset UI outputs to their initial state
372
+ # gemini_key and gemini_model are passed back with their *current* (likely valid) state
373
  yield (history, None, STATE_IDLE, "<p>No Space created yet.</p>", "", "", 0,
374
+ None, None, None, False,
375
+ gemini_api_key, gemini_model) # Reset use_grounding to default False, other states to None/default
376
  # No return needed after yield in this generator pattern; execution for this click ends here.
377
 
378
  elif generate_match:
 
385
  repo_name = new_repo_name
386
  app_desc = new_app_desc
387
  # Yield updated history and state variables (pass UI outputs through)
 
388
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
389
+ attempts, app_desc, repo_name, generated_code, use_grounding,
390
+ gemini_api_key, gemini_model)
391
  # No return needed
392
 
393
  elif create_match:
 
397
  state = STATE_CREATING_SPACE # Transition state to creation
398
  repo_name = new_repo_name # Store the validated repo name
399
  # Yield updated history and state variables (pass UI outputs through)
 
400
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
401
+ attempts, app_desc, repo_name, generated_code, use_grounding,
402
+ gemini_api_key, gemini_model)
403
  # No return needed
404
 
405
  elif "create" in message.lower() and not repo_id:
 
407
  history = add_bot_message(history, "Okay, what should the Space be called? (e.g., `my-awesome-app`)")
408
  state = STATE_AWAITING_REPO_NAME # Transition to the state where we wait for the name
409
  # Yield updated history and state (pass UI outputs through)
 
410
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
411
+ attempts, app_desc, repo_name, generated_code, use_grounding,
412
+ gemini_api_key, gemini_model)
413
  # No return needed
414
 
415
  else:
416
  # Command not recognized in IDLE state
417
  history = add_bot_message(history, "Command not recognized. Try 'generate me a gradio app called myapp', or 'reset'.")
418
  # Yield updated history and current state (pass UI outputs through)
 
419
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
420
+ attempts, app_desc, repo_name, generated_code, use_grounding,
421
+ gemini_api_key, gemini_model)
422
  # No return needed
423
 
424
 
 
430
  if not new_repo_name or re.search(r'[^a-zA-Z0-9_-]', new_repo_name) or len(new_repo_name) > 100:
431
  history = add_bot_message(history, "Invalid name. Please provide a single word/slug for the Space name (letters, numbers, underscores, hyphens only, max 100 chars).")
432
  # Stay in AWAITING_REPO_NAME state and yield message (pass UI outputs through)
 
433
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
434
+ attempts, app_desc, repo_name, generated_code, use_grounding,
435
+ gemini_api_key, gemini_model)
436
  # No return needed
437
 
438
  else:
 
441
  repo_name = new_repo_name # Store the validated repo name
442
  # Yield updated history, state, and repo name. UI outputs remain unchanged for now.
443
  # The next click will proceed from the STATE_CREATING_SPACE block.
 
444
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
445
+ attempts, app_desc, repo_name, generated_code, use_grounding,
446
+ gemini_api_key, gemini_model)
447
  # No return needed
448
 
449
  # Note: Each 'elif' block below represents a distinct step in the workflow triggered
 
454
  if not repo_name:
455
  history = add_bot_message(history, "Internal error: Repo name missing for creation. Resetting.")
456
  # Reset relevant states and UI outputs on critical error
 
457
  yield (history, None, STATE_IDLE, "<p>Error creating space.</p>", "", "", 0,
458
+ None, None, None, use_grounding,
459
+ gemini_api_key, gemini_model) # Pass grounding state through
460
  # No return needed
461
 
462
  else:
 
468
  history = add_bot_message(history, f"βœ… Space `{repo_id}` created. Click 'Send' to generate and upload code.")
469
  state = STATE_GENERATING_CODE # Transition to the next state
470
  # Yield updated state variables and history, and the new iframe HTML
 
471
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
472
+ attempts, app_desc, repo_name, generated_code, use_grounding,
473
+ gemini_api_key, gemini_model) # Pass logs and grounding through
474
  # No return needed
475
 
476
  except Exception as e:
477
  history = add_bot_message(history, f"❌ Error creating space: {e}. Click 'reset'.")
478
  # Yield error message and reset state on failure
 
479
  yield (history, None, STATE_IDLE, "<p>Error creating space.</p>", "", "", 0,
480
+ None, None, None, use_grounding,
481
+ gemini_api_key, gemini_model) # Pass logs and grounding through
482
  # No return needed
483
 
484
 
 
497
  if use_grounding:
498
  history = add_bot_message(history, "(Using Grounding with Google Search)")
499
  # Yield to show message before the potentially time-consuming API call
 
500
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
501
+ attempts, app_desc, repo_name, generated_code, use_grounding,
502
+ gemini_api_key, gemini_model)
503
 
504
  # Perform the Gemini API call to generate code, optionally using grounding
505
  # Use the gemini_api_key and gemini_model inputs directly (which come from state)
 
520
  state = STATE_UPLOADING_APP_PY # Transition to the upload state
521
  generated_code = code # Store the generated code in the state variable for the next step
522
  # Yield updated state variables and history (pass UI outputs and other states through)
 
523
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
524
+ attempts, app_desc, repo_name, generated_code, use_grounding,
525
+ gemini_api_key, gemini_model)
526
  # No return needed
527
 
528
  except Exception as e:
529
  history = add_bot_message(history, f"❌ Error generating code: {e}. Click 'reset'.")
530
  # Yield error message and reset state on failure
 
531
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
532
+ None, None, None, use_grounding,
533
+ gemini_api_key, gemini_model)
534
  # No return needed
535
 
536
 
 
539
  code_to_upload = generated_code
540
  if not code_to_upload:
541
  history = add_bot_message(history, "Internal error: No code to upload. Resetting.")
 
542
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
543
+ None, None, None, use_grounding,
544
+ gemini_api_key, gemini_model)
545
  # No return needed
546
 
547
  else:
548
  history = add_bot_message(history, "☁️ Uploading `app.py`...")
549
  # Yield to show message before the upload action (pass UI outputs and states through)
 
550
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
551
+ attempts, app_desc, repo_name, generated_code, use_grounding,
552
+ gemini_api_key, gemini_model)
553
 
554
  try:
555
  # Perform the file upload action
 
558
  state = STATE_GENERATING_REQUIREMENTS # Transition state
559
  generated_code = None # Clear the stored code after use to free memory/state space
560
  # Yield updated state variables and history (pass UI outputs and other states through)
 
561
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
562
+ attempts, app_desc, repo_name, generated_code, use_grounding,
563
+ gemini_api_key, gemini_model)
564
  # No return needed
565
 
566
  except Exception as e:
567
  history = add_bot_message(history, f"❌ Error uploading `app.py`: {e}. Click 'reset'.")
568
  # Yield error message and reset state on failure
 
569
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
570
+ None, None, None, use_grounding,
571
+ gemini_api_key, gemini_model)
572
  # No return needed
573
 
574
 
575
  elif state == STATE_GENERATING_REQUIREMENTS:
576
  history = add_bot_message(history, "πŸ“„ Generating `requirements.txt`...")
577
  # Yield to show message before generating requirements (pass UI outputs and states through)
 
578
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
579
+ attempts, app_desc, repo_name, generated_code, use_grounding,
580
+ gemini_api_key, gemini_model)
581
 
582
  # Logic to determine required packages based on SDK and keywords in the app description
583
  reqs_list = ["gradio"] if space_sdk == "gradio" else ["streamlit"]
 
618
  state = STATE_UPLOADING_REQUIREMENTS # Transition state
619
  generated_code = reqs_content # Store requirements content
620
  # Yield updated state variables and history (pass UI outputs and other states through)
 
621
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
622
+ attempts, app_desc, repo_name, generated_code, use_grounding,
623
+ gemini_api_key, gemini_model)
624
  # No return needed
625
 
626
 
 
629
  reqs_content_to_upload = generated_code
630
  if not reqs_content_to_upload:
631
  history = add_bot_message(history, "Internal error: No requirements content to upload. Resetting.")
 
632
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
633
+ None, None, None, use_grounding,
634
+ gemini_api_key, gemini_model)
635
  # No return needed
636
 
637
  else:
638
  history = add_bot_message(history, "☁️ Uploading `requirements.txt`...")
639
  # Yield message before upload (pass UI outputs and states through)
 
640
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
641
+ attempts, app_desc, repo_name, generated_code, use_grounding,
642
+ gemini_api_key, gemini_model)
643
 
644
  try:
645
  # Perform requirements file upload
 
648
  state = STATE_GENERATING_README # Transition state
649
  generated_code = None # Clear content after use
650
  # Yield updated state variables and history (pass UI outputs and other states through)
 
651
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
652
+ attempts, app_desc, repo_name, generated_code, use_grounding,
653
+ gemini_api_key, gemini_model)
654
  # No return needed
655
 
656
  except Exception as e:
657
  history = add_bot_message(history, f"❌ Error uploading `requirements.txt`: {e}. Click 'reset'.")
658
  # Yield error message and reset state on failure
 
659
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
660
+ None, None, None, use_grounding,
661
+ gemini_api_key, gemini_model)
662
  # No return needed
663
 
664
  elif state == STATE_GENERATING_README:
665
  history = add_bot_message(history, "πŸ“ Generating `README.md`...")
666
  # Yield message before generating README (pass UI outputs and states through)
 
667
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
668
+ attempts, app_desc, repo_name, generated_code, use_grounding,
669
+ gemini_api_key, gemini_model)
670
 
671
  # Generate simple README content with Space metadata header
672
  readme_title = repo_name if repo_name else "My Awesome Space"
 
693
  state = STATE_UPLOADING_README # Transition state
694
  generated_code = readme_content # Store README content
695
  # Yield updated state variables and history (pass UI outputs and other states through)
 
696
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
697
+ attempts, app_desc, repo_name, generated_code, use_grounding,
698
+ gemini_api_key, gemini_model)
699
  # No return needed
700
 
701
 
 
704
  readme_content_to_upload = generated_code
705
  if not readme_content_to_upload:
706
  history = add_bot_message(history, "Internal error: No README content to upload. Resetting.")
 
707
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
708
+ None, None, None, use_grounding,
709
+ gemini_api_key, gemini_model)
710
  # No return needed
711
 
712
  else:
713
  history = add_bot_message(history, "☁️ Uploading `README.md`...")
714
  # Yield message before upload (pass UI outputs and states through)
 
715
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
716
+ attempts, app_desc, repo_name, generated_code, use_grounding,
717
+ gemini_api_key, gemini_model)
718
 
719
  try:
720
  # Perform README file upload
 
723
  state = STATE_CHECKING_LOGS_BUILD # Transition to checking build logs
724
  generated_code = None # Clear content after use
725
  # Yield updated state variables and history (pass UI outputs and other states through)
 
726
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
727
+ attempts, app_desc, repo_name, generated_code, use_grounding,
728
+ gemini_api_key, gemini_model)
729
  # No return needed
730
 
731
  except Exception as e:
732
  history = add_bot_message(history, f"❌ Error uploading `README.md`: {e}. Click 'reset'.")
733
  # Yield error message and reset state on failure
 
734
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
735
+ None, None, None, use_grounding,
736
+ gemini_api_key, gemini_model)
737
  # No return needed
738
 
739
  elif state == STATE_CHECKING_LOGS_BUILD:
740
  history = add_bot_message(history, "πŸ” Fetching build logs...")
741
  # Yield message before fetching logs (which includes a delay) (pass UI outputs and states through)
 
742
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
743
+ attempts, app_desc, repo_name, generated_code, use_grounding,
744
+ gemini_api_key, gemini_model)
745
 
746
  # Fetch build logs from HF Space
747
  build_logs_text = get_build_logs_action(repo_id, hf_profile, hf_token)
 
752
  history = add_bot_message(history, "⚠️ Build logs indicate potential issues. Please inspect above. Click 'Send' to check container logs (app might still start despite build warnings).")
753
  state = STATE_CHECKING_LOGS_RUN # Transition even on build error, to see if container starts
754
  # Yield updated state, logs, and variables
 
755
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
756
+ attempts, app_desc, repo_name, generated_code, use_grounding,
757
+ gemini_api_key, gemini_model)
758
  # No return needed
759
 
760
  else:
761
  history = add_bot_message(history, "βœ… Build logs fetched. Click 'Send' to check container logs.")
762
  state = STATE_CHECKING_LOGS_RUN # Transition to next log check
763
  # Yield updated state, logs, and variables
 
764
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
765
+ attempts, app_desc, repo_name, generated_code, use_grounding,
766
+ gemini_api_key, gemini_model)
767
  # No return needed
768
 
769
 
770
  elif state == STATE_CHECKING_LOGS_RUN:
771
  history = add_bot_message(history, "πŸ” Fetching container logs...")
772
  # Yield message before fetching logs (includes a delay) (pass UI outputs and states through)
 
773
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
774
+ attempts, app_desc, repo_name, generated_code, use_grounding,
775
+ gemini_api_key, gemini_model)
776
 
777
  # Fetch container logs from HF Space
778
  container_logs_text = get_container_logs_action(repo_id, hf_profile, hf_token)
 
784
  history = add_bot_message(history, f"❌ Errors detected in container logs. Attempting debug fix #{attempts}/{MAX_DEBUG_ATTEMPTS}. Click 'Send' to proceed.")
785
  state = STATE_DEBUGGING_CODE # Transition to the debugging state
786
  # Yield updated state, logs, attempts, and variables
 
787
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
788
+ attempts, app_desc, repo_name, generated_code, use_grounding,
789
+ gemini_api_key, gemini_model)
790
  # No return needed
791
 
792
  elif ("error" in updated_run.lower() or "exception" in updated_run.lower()) and attempts >= MAX_DEBUG_ATTEMPTS:
 
794
  history = add_bot_message(history, f"❌ Errors detected in container logs. Max debug attempts ({MAX_DEBUG_ATTEMPTS}) reached. Please inspect logs manually or click 'reset'.")
795
  state = STATE_COMPLETE # Workflow ends on failure after attempts
796
  # Yield updated state, logs, attempts, and variables
 
797
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
798
+ attempts, app_desc, repo_name, generated_code, use_grounding,
799
+ gemini_api_key, gemini_model)
800
  # No return needed
801
 
802
  else:
 
804
  history = add_bot_message(history, "βœ… App appears to be running successfully! Check the iframe above. Click 'reset' to start a new project.")
805
  state = STATE_COMPLETE # Workflow ends on success
806
  # Yield updated state, logs, attempts, and variables
 
807
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
808
+ attempts, app_desc, repo_name, generated_code, use_grounding,
809
+ gemini_api_key, gemini_model)
810
  # No return needed
811
 
812
 
 
815
  if use_grounding:
816
  history = add_bot_message(history, "(Using Grounding with Google Search)")
817
  # Yield message before Gemini API call (pass UI outputs and states through)
 
818
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
819
+ attempts, app_desc, repo_name, generated_code, use_grounding,
820
+ gemini_api_key, gemini_model)
821
 
822
  # Construct prompt for Gemini including the container logs
823
  debug_prompt = f"""
 
852
  state = STATE_UPLOADING_FIXED_APP_PY # Transition to the upload state for the fix
853
  generated_code = fix_code # Store the generated fix code
854
  # Yield updated state, code, and variables (pass UI outputs and states through)
 
855
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
856
+ attempts, app_desc, repo_name, generated_code, use_grounding,
857
+ gemini_api_key, gemini_model)
858
  # No return needed
859
 
860
  except Exception as e:
861
  history = add_bot_message(history, f"❌ Error generating debug code: {e}. Click 'reset'.")
862
  # Yield error message and reset state on failure
 
863
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
864
+ None, None, None, use_grounding,
865
+ gemini_api_key, gemini_model)
866
  # No return needed
867
 
868
  elif state == STATE_UPLOADING_FIXED_APP_PY:
 
870
  fixed_code_to_upload = generated_code
871
  if not fixed_code_to_upload:
872
  history = add_bot_message(history, "Internal error: No fixed code available to upload. Resetting.")
 
873
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
874
+ None, None, None, use_grounding,
875
+ gemini_api_key, gemini_model)
876
  # No return needed
877
 
878
  else:
879
  history = add_bot_message(history, "☁️ Uploading fixed `app.py`...")
880
  # Yield message before upload (pass UI outputs and states through)
 
881
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
882
+ attempts, app_desc, repo_name, generated_code, use_grounding,
883
+ gemini_api_key, gemini_model)
884
 
885
  try:
886
  # Perform the upload of the fixed app.py
 
889
  state = STATE_CHECKING_LOGS_RUN # Go back to checking run logs after uploading the fix
890
  generated_code = None # Clear code after use
891
  # Yield updated state, code, and variables (pass UI outputs and states through)
 
892
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
893
+ attempts, app_desc, repo_name, generated_code, use_grounding,
894
+ gemini_api_key, gemini_model)
895
  # No return needed
896
 
897
  except Exception as e:
898
  history = add_bot_message(history, f"❌ Error uploading fixed `app.py`: {e}. Click 'reset'.")
899
  # Yield error message and reset state on failure
 
900
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
901
+ None, None, None, use_grounding,
902
+ gemini_api_key, gemini_model)
903
  # No return needed
904
 
905
  elif state == STATE_COMPLETE:
906
  # If in the complete state, the workflow is finished for this project.
907
  # Subsequent clicks just add user messages; we simply yield the current state.
 
908
  yield (history, repo_id, state, updated_preview, updated_run, updated_build,
909
+ attempts, app_desc, repo_name, generated_code, use_grounding,
910
+ gemini_api_key, gemini_model)
911
  # No return needed
912
 
913
 
 
917
  history = add_bot_message(history, error_message)
918
  print(f"Critical Error in state {state}: {e}") # Log the error for debugging purposes
919
  # Yield an error state and reset essential workflow variables on critical failure
 
920
  yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
921
+ None, None, None, use_grounding,
922
+ gemini_api_key, gemini_model) # Include use_grounding and Gemini states
923
  # No return needed after yield
924
 
925
 
 
1094
  repo_id, workflow, # Update workflow State variables
1095
  iframe, run_txt, build_txt, # Update UI component outputs
1096
  debug_attempts, app_description, repo_name_state, generated_code_state, # Update other State variables
1097
+ use_grounding_state, # Update the grounding state output
1098
+ # ADDED BACK: gemini_key, gemini_model to outputs to ensure state consistency
1099
+ gemini_key, gemini_model
1100
  ]
1101
  ).success( # Chain a .success() event to run *after* the .click() handler completes without error
1102
  # Clear the user input textbox after the message is sent and processed