Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -168,7 +168,7 @@ def add_bot_message(history: list[dict], bot_message: str) -> list[dict]:
|
|
168 |
|
169 |
def ai_workflow_chat(
|
170 |
message: str,
|
171 |
-
history: list[dict],
|
172 |
hf_profile: gr.OAuthProfile | None,
|
173 |
hf_token: gr.OAuthToken | None,
|
174 |
gemini_api_key: str | None,
|
@@ -184,16 +184,16 @@ def ai_workflow_chat(
|
|
184 |
repo_name_state: str | None,
|
185 |
generated_code_state: str | None,
|
186 |
) -> tuple[
|
187 |
-
list[dict],
|
188 |
-
str | None,
|
189 |
-
str,
|
190 |
-
str,
|
191 |
-
str,
|
192 |
-
str,
|
193 |
-
int,
|
194 |
-
str | None,
|
195 |
-
str | None,
|
196 |
-
str | None,
|
197 |
]:
|
198 |
# Unpack state variables
|
199 |
repo_id = repo_id_state
|
@@ -214,7 +214,7 @@ def ai_workflow_chat(
|
|
214 |
user_message_entry["name"] = hf_profile.username
|
215 |
history.append(user_message_entry)
|
216 |
|
217 |
-
# Yield immediately to show user message
|
218 |
yield history, repo_id, state, updated_preview, updated_run, updated_build, attempts, app_desc, repo_name, generated_code
|
219 |
|
220 |
|
@@ -272,7 +272,7 @@ def ai_workflow_chat(
|
|
272 |
|
273 |
if state == STATE_AWAITING_REPO_NAME:
|
274 |
new_repo_name = message.strip()
|
275 |
-
if not new_repo_name or re.search(r'[^a-zA-Z0-9_-]', new_repo_name):
|
276 |
history = add_bot_message(history, "Invalid name. Please provide a single word/slug for the Space name (letters, numbers, underscores, hyphens only).")
|
277 |
yield history, repo_id, state, updated_preview, updated_run, updated_build, attempts, app_desc, repo_name, generated_code
|
278 |
else:
|
@@ -364,15 +364,15 @@ Return **only** the python code block for app.py. Do not include any extra text,
|
|
364 |
if "requests" in str(app_desc).lower():
|
365 |
reqs_list.append("requests")
|
366 |
reqs_list.append("huggingface_hub")
|
367 |
-
if "image" in str(app_desc).lower() or "upload" in str(app_desc).lower() or "blur" in str(app_desc).lower() or "vision" in str(app_desc).lower():
|
368 |
reqs_list.append("Pillow")
|
369 |
if "numpy" in str(app_desc).lower(): reqs_list.append("numpy")
|
370 |
if "pandas" in str(app_desc).lower(): reqs_list.append("pandas")
|
371 |
-
if "scikit-image" in str(app_desc).lower() or "skimage" in str(app_desc).lower() or "cv2" in str(app_desc).lower() or "opencv-python" in str(app_desc).lower():
|
372 |
-
reqs_list.append("scikit-image")
|
373 |
-
reqs_list.append("opencv-python")
|
374 |
|
375 |
-
reqs_list = list(dict.fromkeys(reqs_list))
|
376 |
|
377 |
reqs_content = "\n".join(reqs_list) + "\n"
|
378 |
|
@@ -544,25 +544,15 @@ Return **only** the python code block for app.py. Do not include any extra text,
|
|
544 |
|
545 |
elif state == STATE_COMPLETE:
|
546 |
# Workflow finished. Stay in this state until reset.
|
547 |
-
|
548 |
-
pass # No further action needed in this state
|
549 |
|
550 |
|
551 |
except Exception as e:
|
552 |
-
# Catch-all for unexpected exceptions in any state
|
553 |
error_message = f"Workflow step failed unexpectedly ({state}): {e}. Click 'Send' to re-attempt this step or 'reset'."
|
554 |
history = add_bot_message(history, error_message)
|
555 |
print(f"Critical Error in state {state}: {e}")
|
556 |
-
# Transition to idle state on unexpected errors
|
557 |
yield history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0, None, None, None
|
558 |
-
return
|
559 |
-
|
560 |
-
|
561 |
-
# Note: Each state block should end with a yield to update the UI/state.
|
562 |
-
# If a state block finishes without yielding, the generator will stop until the next call.
|
563 |
-
# By yielding the state variables *after* adding the user message, and then yielding
|
564 |
-
# again after state transitions/actions *within* the state logic, we ensure updates.
|
565 |
-
# The final yield after the try/except is removed as yields should happen within the state logic.
|
566 |
|
567 |
|
568 |
# --- Build the Gradio UI ---
|
@@ -579,7 +569,7 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
579 |
debug_attempts = gr.State(0)
|
580 |
app_description = gr.State(None)
|
581 |
repo_name_state = gr.State(None)
|
582 |
-
generated_code_state = gr.State(None)
|
583 |
|
584 |
with gr.Row():
|
585 |
# Sidebar
|
@@ -592,14 +582,17 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
592 |
# Removed _preprocess=False
|
593 |
ai_builder_tab.load(show_profile, outputs=login_status)
|
594 |
# Update status on login click
|
|
|
595 |
login_btn.click(show_profile, outputs=login_status)
|
596 |
# Store profile and token in state on login click
|
|
|
597 |
login_btn.click(lambda x: x, inputs=[login_btn], outputs=[hf_profile, hf_token])
|
598 |
|
599 |
gr.Markdown("## Google AI Studio API Key")
|
600 |
gemini_input = gr.Textbox(label="API Key", type="password", interactive=True)
|
601 |
gemini_status = gr.Markdown("")
|
602 |
|
|
|
603 |
gemini_input.change(lambda k: k, inputs=gemini_input, outputs=gemini_key)
|
604 |
|
605 |
gr.Markdown("## Gemini Model")
|
@@ -613,6 +606,7 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
613 |
label="Select model",
|
614 |
interactive=True
|
615 |
)
|
|
|
616 |
model_selector.change(lambda m: m, inputs=model_selector, outputs=gemini_model)
|
617 |
|
618 |
# Configure Gemini status on load and when key/model changes
|
@@ -622,23 +616,23 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
622 |
inputs=[gemini_key, gemini_model],
|
623 |
outputs=[gemini_status]
|
624 |
)
|
625 |
-
#
|
626 |
gemini_input.change(
|
627 |
configure_gemini,
|
628 |
inputs=[gemini_key, gemini_model],
|
629 |
-
outputs=[gemini_status]
|
630 |
-
_preprocess=False
|
631 |
)
|
|
|
632 |
model_selector.change(
|
633 |
configure_gemini,
|
634 |
inputs=[gemini_key, gemini_model],
|
635 |
-
outputs=[gemini_status]
|
636 |
-
_preprocess=False
|
637 |
)
|
638 |
|
639 |
|
640 |
gr.Markdown("## Space SDK")
|
641 |
sdk_selector = gr.Radio(choices=["gradio","streamlit"], value="gradio", label="Template SDK", interactive=True)
|
|
|
642 |
sdk_selector.change(lambda s: s, inputs=sdk_selector, outputs=sdk_state)
|
643 |
|
644 |
gr.Markdown("## Workflow Status")
|
@@ -663,24 +657,23 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
663 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
664 |
outputs=[send_btn]
|
665 |
)
|
666 |
-
#
|
667 |
login_btn.click(
|
668 |
update_send_button_state,
|
669 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
670 |
-
outputs=[send_btn]
|
671 |
-
_preprocess=False
|
672 |
)
|
|
|
673 |
gemini_input.change(
|
674 |
update_send_button_state,
|
675 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
676 |
-
outputs=[send_btn]
|
677 |
-
_preprocess=False
|
678 |
)
|
|
|
679 |
model_selector.change(
|
680 |
update_send_button_state,
|
681 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
682 |
-
outputs=[send_btn]
|
683 |
-
_preprocess=False
|
684 |
)
|
685 |
|
686 |
iframe = gr.HTML("<p>No Space created yet.</p>")
|
@@ -688,6 +681,7 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
688 |
run_txt = gr.Textbox(label="Container Logs", lines=10, interactive=False, value="")
|
689 |
|
690 |
# The main event handler for the Send button
|
|
|
691 |
send_btn.click(
|
692 |
ai_workflow_chat,
|
693 |
inputs=[
|
@@ -704,14 +698,16 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
704 |
iframe, run_txt, build_txt,
|
705 |
debug_attempts, app_description, repo_name_state, generated_code_state
|
706 |
]
|
707 |
-
).success(
|
708 |
lambda: gr.update(value=""),
|
709 |
inputs=None,
|
710 |
outputs=user_input
|
711 |
)
|
712 |
|
713 |
# Link state variables to UI status displays (reactive updates)
|
|
|
714 |
workflow.change(lambda s: s, inputs=workflow, outputs=status_text)
|
|
|
715 |
repo_id.change(lambda r: r if r else "None", inputs=repo_id, outputs=repo_id_text)
|
716 |
|
717 |
|
@@ -719,7 +715,6 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
719 |
def greet():
|
720 |
return [{"role": "assistant", "content": "Welcome! Please log in to Hugging Face and provide your Google AI Studio API key to start building Spaces. Once ready, type 'generate me a gradio app called myapp' or 'create' to begin."}]
|
721 |
|
722 |
-
# THIS CALL IS INSIDE the with gr.Blocks() block
|
723 |
ai_builder_tab.load(greet, outputs=chatbot)
|
724 |
|
725 |
|
|
|
168 |
|
169 |
def ai_workflow_chat(
|
170 |
message: str,
|
171 |
+
history: list[dict],
|
172 |
hf_profile: gr.OAuthProfile | None,
|
173 |
hf_token: gr.OAuthToken | None,
|
174 |
gemini_api_key: str | None,
|
|
|
184 |
repo_name_state: str | None,
|
185 |
generated_code_state: str | None,
|
186 |
) -> tuple[
|
187 |
+
list[dict],
|
188 |
+
str | None,
|
189 |
+
str,
|
190 |
+
str,
|
191 |
+
str,
|
192 |
+
str,
|
193 |
+
int,
|
194 |
+
str | None,
|
195 |
+
str | None,
|
196 |
+
str | None,
|
197 |
]:
|
198 |
# Unpack state variables
|
199 |
repo_id = repo_id_state
|
|
|
214 |
user_message_entry["name"] = hf_profile.username
|
215 |
history.append(user_message_entry)
|
216 |
|
217 |
+
# Yield immediately to show user message
|
218 |
yield history, repo_id, state, updated_preview, updated_run, updated_build, attempts, app_desc, repo_name, generated_code
|
219 |
|
220 |
|
|
|
272 |
|
273 |
if state == STATE_AWAITING_REPO_NAME:
|
274 |
new_repo_name = message.strip()
|
275 |
+
if not new_repo_name or re.search(r'[^a-zA-Z0-9_-]', new_repo_name):
|
276 |
history = add_bot_message(history, "Invalid name. Please provide a single word/slug for the Space name (letters, numbers, underscores, hyphens only).")
|
277 |
yield history, repo_id, state, updated_preview, updated_run, updated_build, attempts, app_desc, repo_name, generated_code
|
278 |
else:
|
|
|
364 |
if "requests" in str(app_desc).lower():
|
365 |
reqs_list.append("requests")
|
366 |
reqs_list.append("huggingface_hub")
|
367 |
+
if "image" in str(app_desc).lower() or "upload" in str(app_desc).lower() or "blur" in str(app_desc).lower() or "vision" in str(app_desc).lower():
|
368 |
reqs_list.append("Pillow")
|
369 |
if "numpy" in str(app_desc).lower(): reqs_list.append("numpy")
|
370 |
if "pandas" in str(app_desc).lower(): reqs_list.append("pandas")
|
371 |
+
if "scikit-image" in str(app_desc).lower() or "skimage" in str(app_desc).lower() or "cv2" in str(app_desc).lower() or "opencv-python" in str(app_desc).lower():
|
372 |
+
reqs_list.append("scikit-image")
|
373 |
+
reqs_list.append("opencv-python")
|
374 |
|
375 |
+
reqs_list = list(dict.fromkeys(reqs_list))
|
376 |
|
377 |
reqs_content = "\n".join(reqs_list) + "\n"
|
378 |
|
|
|
544 |
|
545 |
elif state == STATE_COMPLETE:
|
546 |
# Workflow finished. Stay in this state until reset.
|
547 |
+
pass
|
|
|
548 |
|
549 |
|
550 |
except Exception as e:
|
|
|
551 |
error_message = f"Workflow step failed unexpectedly ({state}): {e}. Click 'Send' to re-attempt this step or 'reset'."
|
552 |
history = add_bot_message(history, error_message)
|
553 |
print(f"Critical Error in state {state}: {e}")
|
|
|
554 |
yield history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0, None, None, None
|
555 |
+
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
556 |
|
557 |
|
558 |
# --- Build the Gradio UI ---
|
|
|
569 |
debug_attempts = gr.State(0)
|
570 |
app_description = gr.State(None)
|
571 |
repo_name_state = gr.State(None)
|
572 |
+
generated_code_state = gr.State(None)
|
573 |
|
574 |
with gr.Row():
|
575 |
# Sidebar
|
|
|
582 |
# Removed _preprocess=False
|
583 |
ai_builder_tab.load(show_profile, outputs=login_status)
|
584 |
# Update status on login click
|
585 |
+
# Removed _preprocess=False
|
586 |
login_btn.click(show_profile, outputs=login_status)
|
587 |
# Store profile and token in state on login click
|
588 |
+
# Removed _preprocess=False
|
589 |
login_btn.click(lambda x: x, inputs=[login_btn], outputs=[hf_profile, hf_token])
|
590 |
|
591 |
gr.Markdown("## Google AI Studio API Key")
|
592 |
gemini_input = gr.Textbox(label="API Key", type="password", interactive=True)
|
593 |
gemini_status = gr.Markdown("")
|
594 |
|
595 |
+
# Removed _preprocess=False
|
596 |
gemini_input.change(lambda k: k, inputs=gemini_input, outputs=gemini_key)
|
597 |
|
598 |
gr.Markdown("## Gemini Model")
|
|
|
606 |
label="Select model",
|
607 |
interactive=True
|
608 |
)
|
609 |
+
# Removed _preprocess=False
|
610 |
model_selector.change(lambda m: m, inputs=model_selector, outputs=gemini_model)
|
611 |
|
612 |
# Configure Gemini status on load and when key/model changes
|
|
|
616 |
inputs=[gemini_key, gemini_model],
|
617 |
outputs=[gemini_status]
|
618 |
)
|
619 |
+
# Removed _preprocess=False
|
620 |
gemini_input.change(
|
621 |
configure_gemini,
|
622 |
inputs=[gemini_key, gemini_model],
|
623 |
+
outputs=[gemini_status]
|
|
|
624 |
)
|
625 |
+
# Removed _preprocess=False
|
626 |
model_selector.change(
|
627 |
configure_gemini,
|
628 |
inputs=[gemini_key, gemini_model],
|
629 |
+
outputs=[gemini_status]
|
|
|
630 |
)
|
631 |
|
632 |
|
633 |
gr.Markdown("## Space SDK")
|
634 |
sdk_selector = gr.Radio(choices=["gradio","streamlit"], value="gradio", label="Template SDK", interactive=True)
|
635 |
+
# Removed _preprocess=False
|
636 |
sdk_selector.change(lambda s: s, inputs=sdk_selector, outputs=sdk_state)
|
637 |
|
638 |
gr.Markdown("## Workflow Status")
|
|
|
657 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
658 |
outputs=[send_btn]
|
659 |
)
|
660 |
+
# Removed _preprocess=False
|
661 |
login_btn.click(
|
662 |
update_send_button_state,
|
663 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
664 |
+
outputs=[send_btn]
|
|
|
665 |
)
|
666 |
+
# Removed _preprocess=False
|
667 |
gemini_input.change(
|
668 |
update_send_button_state,
|
669 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
670 |
+
outputs=[send_btn]
|
|
|
671 |
)
|
672 |
+
# Removed _preprocess=False
|
673 |
model_selector.change(
|
674 |
update_send_button_state,
|
675 |
inputs=[hf_profile, hf_token, gemini_key, gemini_model],
|
676 |
+
outputs=[send_btn]
|
|
|
677 |
)
|
678 |
|
679 |
iframe = gr.HTML("<p>No Space created yet.</p>")
|
|
|
681 |
run_txt = gr.Textbox(label="Container Logs", lines=10, interactive=False, value="")
|
682 |
|
683 |
# The main event handler for the Send button
|
684 |
+
# Removed _preprocess=False (it wasn't on this one anyway)
|
685 |
send_btn.click(
|
686 |
ai_workflow_chat,
|
687 |
inputs=[
|
|
|
698 |
iframe, run_txt, build_txt,
|
699 |
debug_attempts, app_description, repo_name_state, generated_code_state
|
700 |
]
|
701 |
+
).success(
|
702 |
lambda: gr.update(value=""),
|
703 |
inputs=None,
|
704 |
outputs=user_input
|
705 |
)
|
706 |
|
707 |
# Link state variables to UI status displays (reactive updates)
|
708 |
+
# Removed _preprocess=False
|
709 |
workflow.change(lambda s: s, inputs=workflow, outputs=status_text)
|
710 |
+
# Removed _preprocess=False
|
711 |
repo_id.change(lambda r: r if r else "None", inputs=repo_id, outputs=repo_id_text)
|
712 |
|
713 |
|
|
|
715 |
def greet():
|
716 |
return [{"role": "assistant", "content": "Welcome! Please log in to Hugging Face and provide your Google AI Studio API key to start building Spaces. Once ready, type 'generate me a gradio app called myapp' or 'create' to begin."}]
|
717 |
|
|
|
718 |
ai_builder_tab.load(greet, outputs=chatbot)
|
719 |
|
720 |
|