Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -229,8 +229,11 @@ def greet():
|
|
229 |
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."}]
|
230 |
|
231 |
# Helper function to update send button interactivity based on prereqs
|
232 |
-
#
|
233 |
-
|
|
|
|
|
|
|
234 |
"""Checks if HF login and Gemini configuration are complete and returns update for button interactivity."""
|
235 |
# --- START ENHANCED DEBUGGING LOGS ---
|
236 |
print("\n--- check_send_button_ready START ---")
|
@@ -240,9 +243,6 @@ def check_send_button_ready(hf_profile: gr.OAuthProfile | None, hf_token: gr.OAu
|
|
240 |
api_key_display = gemini_key[:5] if isinstance(gemini_key, str) and gemini_key else ('Empty String' if isinstance(gemini_key, str) and gemini_key == "" else 'None')
|
241 |
print(f" Received gemini_key: Type={type(gemini_key)}, Value={api_key_display}")
|
242 |
print(f" Received gemini_model: Type={type(gemini_model)}, Value={gemini_model}")
|
243 |
-
# DEBUG PRINTS for unexpected args/kwargs
|
244 |
-
print(f" Received *args: {args}")
|
245 |
-
print(f" Received **kwargs: {kwargs}")
|
246 |
# --- END ENHANCED DEBUGGING LOGS ---
|
247 |
|
248 |
is_logged_in = hf_profile is not None and hf_token is not None
|
@@ -267,6 +267,7 @@ def check_send_button_ready(hf_profile: gr.OAuthProfile | None, hf_token: gr.OAu
|
|
267 |
# It MUST also yield/return ALL state variables in the same order they appear in the `outputs` list of the `.click()` event.
|
268 |
# MODIFIED: Input parameter names align with renamed states for clarity
|
269 |
# MODIFIED: Output tuple includes renamed gemini state variables
|
|
|
270 |
def ai_workflow_chat(
|
271 |
message: str,
|
272 |
history: list[dict],
|
@@ -287,7 +288,7 @@ def ai_workflow_chat(
|
|
287 |
repo_name_state: str | None,
|
288 |
generated_code_state: str | None,
|
289 |
use_grounding_state: bool, # Value from use_grounding_checkbox
|
290 |
-
# Absorb potential extra args passed by Gradio event listeners (e.g. old value, event data)
|
291 |
*args,
|
292 |
**kwargs
|
293 |
) -> tuple[
|
@@ -925,7 +926,6 @@ Return **only** the python code block for app.py. Do not include any extra text,
|
|
925 |
error_message = f"Workflow step failed unexpectedly ({state}): {e}. Click 'Send' to re-attempt this step or 'reset'."
|
926 |
history = add_bot_message(history, error_message)
|
927 |
print(f"Critical Error in state {state}: {e}") # Log the error for debugging purposes
|
928 |
-
# Yield an error state and reset essential workflow variables on critical failure
|
929 |
yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
|
930 |
None, None, None, use_grounding,
|
931 |
current_gemini_key, current_gemini_model) # Include use_grounding and Gemini states
|
@@ -962,6 +962,8 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
962 |
gemini_api_key_state, # Use new state name
|
963 |
gemini_model_state # Use new state name
|
964 |
]
|
|
|
|
|
965 |
|
966 |
|
967 |
with gr.Row():
|
@@ -1034,55 +1036,75 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
1034 |
|
1035 |
# --- Define Event Handlers and Chains AFTER all components are defined ---
|
1036 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1037 |
|
1038 |
-
|
1039 |
-
#
|
1040 |
login_btn.click(
|
1041 |
lambda x: (x[0], x[1]),
|
1042 |
inputs=[login_btn],
|
1043 |
-
outputs=[hf_profile, hf_token] #
|
1044 |
-
)
|
1045 |
-
# Call the update function and bind its output to the button component
|
1046 |
-
check_send_button_ready,
|
1047 |
-
inputs=send_button_interactive_binding_inputs, # Use the explicit list with renamed states
|
1048 |
-
outputs=[send_btn] # Update button interactivity using gr.update return value
|
1049 |
-
)
|
1050 |
|
1051 |
-
# Handle Gemini Key Input change: Update key state -> Configure Gemini status ->
|
1052 |
-
# This chain is crucial for the new key handling logic
|
1053 |
gemini_input.change(
|
1054 |
lambda k: k,
|
1055 |
inputs=[gemini_input],
|
1056 |
-
outputs=[gemini_api_key_state] #
|
1057 |
).then(
|
1058 |
# Use RENAMED state variables as inputs to configure_gemini
|
1059 |
configure_gemini,
|
1060 |
inputs=[gemini_api_key_state, gemini_model_state],
|
1061 |
outputs=[gemini_status] # Update Gemini status based on new key
|
1062 |
-
).then(
|
1063 |
-
# Call the update function and bind its output to the button component
|
1064 |
-
check_send_button_ready,
|
1065 |
-
inputs=send_button_interactive_binding_inputs, # Use the explicit list with renamed states
|
1066 |
-
outputs=[send_btn] # Update button interactivity using gr.update return value
|
1067 |
-
)
|
1068 |
|
1069 |
-
# Handle Gemini Model Selector change: Update model state -> Configure Gemini status ->
|
1070 |
-
# This chain is crucial for the new key handling logic
|
1071 |
model_selector.change(
|
1072 |
lambda m: m,
|
1073 |
inputs=[model_selector],
|
1074 |
-
outputs=[gemini_model_state] #
|
1075 |
).then(
|
1076 |
# Use RENAMED state variables as inputs to configure_gemini
|
1077 |
configure_gemini,
|
1078 |
inputs=[gemini_api_key_state, gemini_model_state],
|
1079 |
outputs=[gemini_status] # Update Gemini status based on new model
|
1080 |
-
).then(
|
1081 |
-
|
1082 |
-
check_send_button_ready,
|
1083 |
-
inputs=send_button_interactive_binding_inputs, # Use the explicit list with renamed states
|
1084 |
-
outputs=[send_btn] # Update button interactivity using gr.update return value
|
1085 |
-
)
|
1086 |
|
1087 |
# Handle Grounding checkbox change: update grounding state
|
1088 |
use_grounding_checkbox.change(
|
@@ -1107,6 +1129,8 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
1107 |
# Outputs are updated by the values yielded from the generator
|
1108 |
# MODIFIED: Inputs use renamed gemini state variables
|
1109 |
# MODIFIED: Outputs include renamed gemini state variables
|
|
|
|
|
1110 |
send_btn.click(
|
1111 |
ai_workflow_chat, # The generator function to run
|
1112 |
inputs=[
|
@@ -1140,29 +1164,19 @@ with gr.Blocks(title="AI-Powered HF Space App Builder") as ai_builder_tab:
|
|
1140 |
# --- Initial Load Event Chain (Defined INSIDE gr.Blocks, AFTER components and initial bindings) ---
|
1141 |
# This chain runs once when the app loads
|
1142 |
ai_builder_tab.load(
|
1143 |
-
# Action 1: Show profile (loads cached login if available)
|
|
|
|
|
1144 |
show_profile,
|
1145 |
inputs=None,
|
1146 |
-
outputs=login_status #
|
1147 |
).then(
|
1148 |
-
# Action 2: Configure Gemini using
|
1149 |
-
# Since gemini_api_key_state state starts as "", this will initially show a "key is not set" message.
|
1150 |
-
# Use RENAMED state variables as inputs
|
1151 |
configure_gemini,
|
1152 |
-
inputs=[gemini_api_key_state, gemini_model_state],
|
1153 |
outputs=[gemini_status] # Update Gemini status display
|
1154 |
-
).then(
|
1155 |
-
|
1156 |
-
# Since gemini_api_key_state state starts as "", button will initially be disabled.
|
1157 |
-
check_send_button_ready,
|
1158 |
-
inputs=send_button_interactive_binding_inputs, # Use the explicit list with renamed states
|
1159 |
-
outputs=[send_btn] # Update button interactivity using gr.update return value
|
1160 |
-
).then(
|
1161 |
-
# Action 4: Add the initial welcome message to the chatbot
|
1162 |
-
greet,
|
1163 |
-
inputs=None,
|
1164 |
-
outputs=chatbot
|
1165 |
-
)
|
1166 |
|
1167 |
|
1168 |
# The main workflow function and other helper functions are correctly defined OUTSIDE the gr.Blocks context
|
|
|
229 |
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."}]
|
230 |
|
231 |
# Helper function to update send button interactivity based on prereqs
|
232 |
+
# MODIFIED: Signature takes exactly 4 inputs, removed *args, **kwargs
|
233 |
+
# FIXED: Return type hint corrected to gr.update
|
234 |
+
# MODIFIED: Internal logic uses bool() check for simplicity
|
235 |
+
# REMOVED: problematic debug prints involving *args, **kwargs
|
236 |
+
def check_send_button_ready(hf_profile: gr.OAuthProfile | None, hf_token: gr.OAuthToken | None, gemini_key: str | None, gemini_model: str | None) -> gr.update:
|
237 |
"""Checks if HF login and Gemini configuration are complete and returns update for button interactivity."""
|
238 |
# --- START ENHANCED DEBUGGING LOGS ---
|
239 |
print("\n--- check_send_button_ready START ---")
|
|
|
243 |
api_key_display = gemini_key[:5] if isinstance(gemini_key, str) and gemini_key else ('Empty String' if isinstance(gemini_key, str) and gemini_key == "" else 'None')
|
244 |
print(f" Received gemini_key: Type={type(gemini_key)}, Value={api_key_display}")
|
245 |
print(f" Received gemini_model: Type={type(gemini_model)}, Value={gemini_model}")
|
|
|
|
|
|
|
246 |
# --- END ENHANCED DEBUGGING LOGS ---
|
247 |
|
248 |
is_logged_in = hf_profile is not None and hf_token is not None
|
|
|
267 |
# It MUST also yield/return ALL state variables in the same order they appear in the `outputs` list of the `.click()` event.
|
268 |
# MODIFIED: Input parameter names align with renamed states for clarity
|
269 |
# MODIFIED: Output tuple includes renamed gemini state variables
|
270 |
+
# REMOVED: *args, **kwargs from signature
|
271 |
def ai_workflow_chat(
|
272 |
message: str,
|
273 |
history: list[dict],
|
|
|
288 |
repo_name_state: str | None,
|
289 |
generated_code_state: str | None,
|
290 |
use_grounding_state: bool, # Value from use_grounding_checkbox
|
291 |
+
# Absorb potential extra args passed by Gradio event listeners (e.g. old value, event data) - RE-ADDED for safety in generator context
|
292 |
*args,
|
293 |
**kwargs
|
294 |
) -> tuple[
|
|
|
926 |
error_message = f"Workflow step failed unexpectedly ({state}): {e}. Click 'Send' to re-attempt this step or 'reset'."
|
927 |
history = add_bot_message(history, error_message)
|
928 |
print(f"Critical Error in state {state}: {e}") # Log the error for debugging purposes
|
|
|
929 |
yield (history, None, STATE_IDLE, updated_preview, updated_run, updated_build, 0,
|
930 |
None, None, None, use_grounding,
|
931 |
current_gemini_key, current_gemini_model) # Include use_grounding and Gemini states
|
|
|
962 |
gemini_api_key_state, # Use new state name
|
963 |
gemini_model_state # Use new state name
|
964 |
]
|
965 |
+
# Define the output for updating the send button interactivity
|
966 |
+
send_button_update_output = [send_btn]
|
967 |
|
968 |
|
969 |
with gr.Row():
|
|
|
1036 |
|
1037 |
# --- Define Event Handlers and Chains AFTER all components are defined ---
|
1038 |
|
1039 |
+
# Define the inputs used for checking prerequisites using the RENAMED states
|
1040 |
+
# Moved definition *after* the state variables are defined
|
1041 |
+
send_button_interactive_binding_inputs = [
|
1042 |
+
hf_profile,
|
1043 |
+
hf_token,
|
1044 |
+
gemini_api_key_state, # Use new state name
|
1045 |
+
gemini_model_state # Use new state name
|
1046 |
+
]
|
1047 |
+
# Define the output for updating the send button interactivity
|
1048 |
+
send_button_update_output = [send_btn]
|
1049 |
+
|
1050 |
+
# Trigger check_send_button_ready whenever any prerequisite state changes
|
1051 |
+
hf_profile.change(
|
1052 |
+
check_send_button_ready,
|
1053 |
+
inputs=send_button_interactive_binding_inputs,
|
1054 |
+
outputs=send_button_update_output,
|
1055 |
+
# run_as_event=True # Added this as a precaution if .change doesn't trigger correctly
|
1056 |
+
)
|
1057 |
+
hf_token.change(
|
1058 |
+
check_send_button_ready,
|
1059 |
+
inputs=send_button_interactive_binding_inputs,
|
1060 |
+
outputs=send_button_update_output,
|
1061 |
+
# run_as_event=True # Added this as a precaution
|
1062 |
+
)
|
1063 |
+
gemini_api_key_state.change(
|
1064 |
+
check_send_button_ready,
|
1065 |
+
inputs=send_button_interactive_binding_inputs,
|
1066 |
+
outputs=send_button_update_output,
|
1067 |
+
# run_as_event=True # Added this as a precaution
|
1068 |
+
)
|
1069 |
+
gemini_model_state.change(
|
1070 |
+
check_send_button_ready,
|
1071 |
+
inputs=send_button_interactive_binding_inputs,
|
1072 |
+
outputs=send_button_update_output,
|
1073 |
+
# run_as_event=True # Added this as a precaution
|
1074 |
+
)
|
1075 |
|
1076 |
+
|
1077 |
+
# Handle login button click: Update profile/token state -> *Now rely on .change handlers to trigger check_send_button_ready*
|
1078 |
login_btn.click(
|
1079 |
lambda x: (x[0], x[1]),
|
1080 |
inputs=[login_btn],
|
1081 |
+
outputs=[hf_profile, hf_token] # Updating these states will trigger their .change handlers
|
1082 |
+
) # Removed .then(check_send_button_ready, ...)
|
|
|
|
|
|
|
|
|
|
|
1083 |
|
1084 |
+
# Handle Gemini Key Input change: Update key state -> Configure Gemini status -> *Now rely on .change handlers to trigger check_send_button_ready*
|
|
|
1085 |
gemini_input.change(
|
1086 |
lambda k: k,
|
1087 |
inputs=[gemini_input],
|
1088 |
+
outputs=[gemini_api_key_state] # Updating this state will trigger its .change handler
|
1089 |
).then(
|
1090 |
# Use RENAMED state variables as inputs to configure_gemini
|
1091 |
configure_gemini,
|
1092 |
inputs=[gemini_api_key_state, gemini_model_state],
|
1093 |
outputs=[gemini_status] # Update Gemini status based on new key
|
1094 |
+
) # Removed .then(check_send_button_ready, ...)
|
|
|
|
|
|
|
|
|
|
|
1095 |
|
1096 |
+
# Handle Gemini Model Selector change: Update model state -> Configure Gemini status -> *Now rely on .change handlers to trigger check_send_button_ready*
|
|
|
1097 |
model_selector.change(
|
1098 |
lambda m: m,
|
1099 |
inputs=[model_selector],
|
1100 |
+
outputs=[gemini_model_state] # Updating this state will trigger its .change handler
|
1101 |
).then(
|
1102 |
# Use RENAMED state variables as inputs to configure_gemini
|
1103 |
configure_gemini,
|
1104 |
inputs=[gemini_api_key_state, gemini_model_state],
|
1105 |
outputs=[gemini_status] # Update Gemini status based on new model
|
1106 |
+
) # Removed .then(check_send_button_ready, ...)
|
1107 |
+
|
|
|
|
|
|
|
|
|
1108 |
|
1109 |
# Handle Grounding checkbox change: update grounding state
|
1110 |
use_grounding_checkbox.change(
|
|
|
1129 |
# Outputs are updated by the values yielded from the generator
|
1130 |
# MODIFIED: Inputs use renamed gemini state variables
|
1131 |
# MODIFIED: Outputs include renamed gemini state variables
|
1132 |
+
# Added back *args, **kwargs to the generator function signature and yield for robustness,
|
1133 |
+
# as the previous attempt suggested this might be necessary for state consistency within the generator's lifecycle.
|
1134 |
send_btn.click(
|
1135 |
ai_workflow_chat, # The generator function to run
|
1136 |
inputs=[
|
|
|
1164 |
# --- Initial Load Event Chain (Defined INSIDE gr.Blocks, AFTER components and initial bindings) ---
|
1165 |
# This chain runs once when the app loads
|
1166 |
ai_builder_tab.load(
|
1167 |
+
# Action 1: Show profile (loads cached login if available)
|
1168 |
+
# This calls show_profile, which updates the login_status UI.
|
1169 |
+
# The LoginButton component itself implicitly handles updating hf_profile/hf_token states on load if cached creds exist.
|
1170 |
show_profile,
|
1171 |
inputs=None,
|
1172 |
+
outputs=login_status # Updates UI
|
1173 |
).then(
|
1174 |
+
# Action 2: Configure Gemini using initial state (gemini_api_key_state is "", model_state is default)
|
|
|
|
|
1175 |
configure_gemini,
|
1176 |
+
inputs=[gemini_api_key_state, gemini_model_state], # Use RENAMED state variables as inputs
|
1177 |
outputs=[gemini_status] # Update Gemini status display
|
1178 |
+
) # Removed .then(check_send_button_ready, ...). The state changes from LoginButton/Gemini init *should* trigger the .change handlers above.
|
1179 |
+
# The greet message will be added automatically by the chat UI initialization.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1180 |
|
1181 |
|
1182 |
# The main workflow function and other helper functions are correctly defined OUTSIDE the gr.Blocks context
|