Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -221,7 +221,8 @@ def _convert_gr_history_to_api_messages(system_prompt, gr_history, current_user_
|
|
221 |
return messages
|
222 |
|
223 |
def _generate_ui_outputs_from_cache(owner, space_name):
|
224 |
-
global
|
|
|
225 |
preview_md_val = "*No files in cache to display.*"
|
226 |
formatted_md_val = f"# Space: {owner}/{space_name}\n## File Structure\n{bbb}\n📁 Root\n{bbb}\n\n*No files in cache.*" if owner or space_name else "*Load or define a Space to see its Markdown structure.*"
|
227 |
download_file = None
|
@@ -263,6 +264,8 @@ def handle_chat_submit(user_message, chat_history, api_key_input, provider_selec
|
|
263 |
try:
|
264 |
parsed_from_md = build_logic_parse_markdown(_current_formatted_markdown)
|
265 |
new_cache_state = []
|
|
|
|
|
266 |
existing_structure_block = next((b for b in parsed_code_blocks_state_cache if b.get("is_structure_block")), None)
|
267 |
if existing_structure_block:
|
268 |
new_cache_state.append(existing_structure_block.copy())
|
@@ -291,6 +294,9 @@ def handle_chat_submit(user_message, chat_history, api_key_input, provider_selec
|
|
291 |
"is_structure_block": False
|
292 |
})
|
293 |
new_cache_state.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"]))
|
|
|
|
|
|
|
294 |
parsed_code_blocks_state_cache = new_cache_state
|
295 |
|
296 |
except Exception as e:
|
@@ -306,6 +312,7 @@ def handle_chat_submit(user_message, chat_history, api_key_input, provider_selec
|
|
306 |
current_sys_prompt = system_prompt.strip() or DEFAULT_SYSTEM_PROMPT
|
307 |
|
308 |
current_files_context = ""
|
|
|
309 |
if parsed_code_blocks_state_cache:
|
310 |
current_files_context = "\n\n## Current Files in Space\n"
|
311 |
for block in parsed_code_blocks_state_cache:
|
@@ -348,13 +355,15 @@ def handle_chat_submit(user_message, chat_history, api_key_input, provider_selec
|
|
348 |
elif full_bot_response_content and not full_bot_response_content.startswith("Error: "):
|
349 |
_status = f"Streaming complete. Processing files from {model_select} response..."
|
350 |
|
|
|
|
|
351 |
parsing_res = _parse_chat_stream_logic(full_bot_response_content, existing_files_state=parsed_code_blocks_state_cache)
|
352 |
|
353 |
if parsing_res["error_message"]:
|
354 |
_status = f"Parsing Error: {parsing_res['error_message']}"
|
355 |
_detected_files_update = gr.Markdown(f"## Parsing Error\n`{escape_html_for_markdown(parsing_res['error_message'])}`")
|
356 |
else:
|
357 |
-
global parsed_code_blocks_state_cache
|
358 |
parsed_code_blocks_state_cache = parsing_res["parsed_code_blocks"]
|
359 |
|
360 |
_formatted_output_update, _detected_files_update, _download_btn_update = _generate_ui_outputs_from_cache(hf_owner_name, hf_repo_name)
|
@@ -502,7 +511,7 @@ def handle_build_space_button(hf_api_key_ui, ui_space_name_part, ui_owner_name_p
|
|
502 |
|
503 |
try:
|
504 |
parsed_from_md_for_build = build_logic_parse_markdown(formatted_markdown_content)
|
505 |
-
parsed_code_blocks_state_cache = []
|
506 |
if parsed_from_md_for_build.get("owner_md"):
|
507 |
ui_owner_name_part = parsed_from_md_for_build["owner_md"]
|
508 |
if parsed_from_md_for_build.get("repo_name_md"):
|
@@ -510,7 +519,7 @@ def handle_build_space_button(hf_api_key_ui, ui_space_name_part, ui_owner_name_p
|
|
510 |
|
511 |
structure_block_md = next((f for f in parsed_from_md_for_build.get("files", []) if f.get("path") == "File Structure (original)"), None)
|
512 |
if structure_block_md:
|
513 |
-
parsed_code_blocks_state_cache.append({
|
514 |
"filename": structure_block_md["path"],
|
515 |
"code": structure_block_md["content"],
|
516 |
"language": "plaintext",
|
@@ -521,14 +530,14 @@ def handle_build_space_button(hf_api_key_ui, ui_space_name_part, ui_owner_name_p
|
|
521 |
for f_info in parsed_from_md_for_build.get("files", []):
|
522 |
if f_info.get("path") and f_info["path"] != "File Structure (original)":
|
523 |
is_binary_repr = isinstance(f_info.get("content"), str) and (f_info["content"].startswith("[Binary file") or f_info["content"].startswith("[Error loading content:") or f_info["content"].startswith("[Binary or Skipped file]"))
|
524 |
-
parsed_code_blocks_state_cache.append({
|
525 |
"filename": f_info["path"],
|
526 |
"code": f_info.get("content", ""),
|
527 |
"language": "binary" if is_binary_repr else _infer_lang_from_filename(f_info["path"]),
|
528 |
"is_binary": is_binary_repr,
|
529 |
"is_structure_block": False
|
530 |
})
|
531 |
-
parsed_code_blocks_state_cache.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"]))
|
532 |
|
533 |
except Exception as e:
|
534 |
_build_status = f"Build Error: Failed to parse Markdown structure before building: {e}";
|
@@ -554,7 +563,7 @@ def handle_build_space_button(hf_api_key_ui, ui_space_name_part, ui_owner_name_p
|
|
554 |
yield _build_status, _iframe_html, _file_browser_update, owner_name_output, space_name_output
|
555 |
|
556 |
def handle_load_file_for_editing(hf_api_key_ui, ui_space_name_part, ui_owner_name_part, selected_file_path):
|
557 |
-
global parsed_code_blocks_state_cache
|
558 |
_file_content_val, _edit_status_val, _commit_msg_val, _lang_update = "", "Error: No file selected.", gr.update(value=""), gr.update(language="python")
|
559 |
if not selected_file_path or selected_file_path in ["No files found", "Error loading files", "Error refreshing files"]:
|
560 |
yield _file_content_val, "Select a file from the dropdown.", _commit_msg_val, _lang_update
|
@@ -625,6 +634,8 @@ def handle_commit_file_changes(hf_api_key_ui, ui_space_name_part, ui_owner_name_
|
|
625 |
|
626 |
if "Successfully updated" in status_msg:
|
627 |
found_in_cache = False
|
|
|
|
|
628 |
for block in parsed_code_blocks_state_cache:
|
629 |
if block["filename"] == file_to_edit_path:
|
630 |
block["code"] = edited_content
|
@@ -634,6 +645,7 @@ def handle_commit_file_changes(hf_api_key_ui, ui_space_name_part, ui_owner_name_
|
|
634 |
found_in_cache = True
|
635 |
break
|
636 |
if not found_in_cache:
|
|
|
637 |
parsed_code_blocks_state_cache = [b for b in parsed_code_blocks_state_cache if b["filename"] != file_to_edit_path]
|
638 |
parsed_code_blocks_state_cache.append({
|
639 |
"filename": file_to_edit_path,
|
@@ -642,7 +654,7 @@ def handle_commit_file_changes(hf_api_key_ui, ui_space_name_part, ui_owner_name_
|
|
642 |
"is_binary": False,
|
643 |
"is_structure_block": False
|
644 |
})
|
645 |
-
parsed_code_blocks_state_cache.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"
|
646 |
|
647 |
_formatted_md_out, _detected_preview_out, _download_btn_out = _generate_ui_outputs_from_cache(owner_to_use, ui_space_name_part)
|
648 |
|
@@ -692,6 +704,7 @@ def handle_delete_file(hf_api_key_ui, ui_space_name_part, ui_owner_name_part, fi
|
|
692 |
new_file_list, err_list = list_space_files_for_browsing(hf_api_key_ui, ui_space_name_part, owner_to_use)
|
693 |
|
694 |
if "Successfully deleted" in deletion_status_msg:
|
|
|
695 |
parsed_code_blocks_state_cache = [b for b in parsed_code_blocks_state_cache if b["filename"] != file_to_delete_path]
|
696 |
_formatted_md_out, _detected_preview_out, _download_btn_out = _generate_ui_outputs_from_cache(owner_to_use, ui_space_name_part)
|
697 |
|
@@ -887,7 +900,7 @@ with gr.Blocks(theme=custom_theme, css=custom_css) as demo:
|
|
887 |
delete_file_outputs = [edit_status_display, file_browser_dropdown, file_browser_dropdown, file_content_editor, commit_message_input, file_content_editor, formatted_space_output_display, detected_files_preview, download_button]
|
888 |
delete_file_button.click(fn=handle_delete_file, inputs=[hf_api_key_input, space_name_input, owner_name_input, file_browser_dropdown], outputs=delete_file_outputs)
|
889 |
|
890 |
-
|
891 |
|
892 |
if __name__ == "__main__":
|
893 |
demo.launch(debug=True, share=False)
|
|
|
221 |
return messages
|
222 |
|
223 |
def _generate_ui_outputs_from_cache(owner, space_name):
|
224 |
+
# This function only reads the global variable, does not need 'global' declaration
|
225 |
+
global parsed_code_blocks_state_cache # Added global here just in case, although technically not needed for reads only.
|
226 |
preview_md_val = "*No files in cache to display.*"
|
227 |
formatted_md_val = f"# Space: {owner}/{space_name}\n## File Structure\n{bbb}\n📁 Root\n{bbb}\n\n*No files in cache.*" if owner or space_name else "*Load or define a Space to see its Markdown structure.*"
|
228 |
download_file = None
|
|
|
264 |
try:
|
265 |
parsed_from_md = build_logic_parse_markdown(_current_formatted_markdown)
|
266 |
new_cache_state = []
|
267 |
+
# This loop accesses parsed_code_blocks_state_cache, but the global declaration
|
268 |
+
# is correctly placed *before* this use in this function.
|
269 |
existing_structure_block = next((b for b in parsed_code_blocks_state_cache if b.get("is_structure_block")), None)
|
270 |
if existing_structure_block:
|
271 |
new_cache_state.append(existing_structure_block.copy())
|
|
|
294 |
"is_structure_block": False
|
295 |
})
|
296 |
new_cache_state.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"]))
|
297 |
+
# This is an assignment to parsed_code_blocks_state_cache.
|
298 |
+
# The 'global' declaration needs to be before the first assignment *or* use.
|
299 |
+
# It is correctly placed at the start of the function.
|
300 |
parsed_code_blocks_state_cache = new_cache_state
|
301 |
|
302 |
except Exception as e:
|
|
|
312 |
current_sys_prompt = system_prompt.strip() or DEFAULT_SYSTEM_PROMPT
|
313 |
|
314 |
current_files_context = ""
|
315 |
+
# This block accesses parsed_code_blocks_state_cache, after the global declaration.
|
316 |
if parsed_code_blocks_state_cache:
|
317 |
current_files_context = "\n\n## Current Files in Space\n"
|
318 |
for block in parsed_code_blocks_state_cache:
|
|
|
355 |
elif full_bot_response_content and not full_bot_response_content.startswith("Error: "):
|
356 |
_status = f"Streaming complete. Processing files from {model_select} response..."
|
357 |
|
358 |
+
# This block accesses and assigns to parsed_code_blocks_state_cache,
|
359 |
+
# after the global declaration at the top of the function.
|
360 |
parsing_res = _parse_chat_stream_logic(full_bot_response_content, existing_files_state=parsed_code_blocks_state_cache)
|
361 |
|
362 |
if parsing_res["error_message"]:
|
363 |
_status = f"Parsing Error: {parsing_res['error_message']}"
|
364 |
_detected_files_update = gr.Markdown(f"## Parsing Error\n`{escape_html_for_markdown(parsing_res['error_message'])}`")
|
365 |
else:
|
366 |
+
global parsed_code_blocks_state_cache # Redundant global, but harmless. The one at the top is effective.
|
367 |
parsed_code_blocks_state_cache = parsing_res["parsed_code_blocks"]
|
368 |
|
369 |
_formatted_output_update, _detected_files_update, _download_btn_update = _generate_ui_outputs_from_cache(hf_owner_name, hf_repo_name)
|
|
|
511 |
|
512 |
try:
|
513 |
parsed_from_md_for_build = build_logic_parse_markdown(formatted_markdown_content)
|
514 |
+
parsed_code_blocks_state_cache = [] # Assignment to global variable
|
515 |
if parsed_from_md_for_build.get("owner_md"):
|
516 |
ui_owner_name_part = parsed_from_md_for_build["owner_md"]
|
517 |
if parsed_from_md_for_build.get("repo_name_md"):
|
|
|
519 |
|
520 |
structure_block_md = next((f for f in parsed_from_md_for_build.get("files", []) if f.get("path") == "File Structure (original)"), None)
|
521 |
if structure_block_md:
|
522 |
+
parsed_code_blocks_state_cache.append({ # Modifies global list
|
523 |
"filename": structure_block_md["path"],
|
524 |
"code": structure_block_md["content"],
|
525 |
"language": "plaintext",
|
|
|
530 |
for f_info in parsed_from_md_for_build.get("files", []):
|
531 |
if f_info.get("path") and f_info["path"] != "File Structure (original)":
|
532 |
is_binary_repr = isinstance(f_info.get("content"), str) and (f_info["content"].startswith("[Binary file") or f_info["content"].startswith("[Error loading content:") or f_info["content"].startswith("[Binary or Skipped file]"))
|
533 |
+
parsed_code_blocks_state_cache.append({ # Modifies global list
|
534 |
"filename": f_info["path"],
|
535 |
"code": f_info.get("content", ""),
|
536 |
"language": "binary" if is_binary_repr else _infer_lang_from_filename(f_info["path"]),
|
537 |
"is_binary": is_binary_repr,
|
538 |
"is_structure_block": False
|
539 |
})
|
540 |
+
parsed_code_blocks_state_cache.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"])) # Modifies global list
|
541 |
|
542 |
except Exception as e:
|
543 |
_build_status = f"Build Error: Failed to parse Markdown structure before building: {e}";
|
|
|
563 |
yield _build_status, _iframe_html, _file_browser_update, owner_name_output, space_name_output
|
564 |
|
565 |
def handle_load_file_for_editing(hf_api_key_ui, ui_space_name_part, ui_owner_name_part, selected_file_path):
|
566 |
+
global parsed_code_blocks_state_cache # This function only reads, does not strictly need global.
|
567 |
_file_content_val, _edit_status_val, _commit_msg_val, _lang_update = "", "Error: No file selected.", gr.update(value=""), gr.update(language="python")
|
568 |
if not selected_file_path or selected_file_path in ["No files found", "Error loading files", "Error refreshing files"]:
|
569 |
yield _file_content_val, "Select a file from the dropdown.", _commit_msg_val, _lang_update
|
|
|
634 |
|
635 |
if "Successfully updated" in status_msg:
|
636 |
found_in_cache = False
|
637 |
+
# Modifies item within the global list. No need for global declaration here if the list itself isn't reassigned.
|
638 |
+
# But if the file was new, it might be added later, which requires global.
|
639 |
for block in parsed_code_blocks_state_cache:
|
640 |
if block["filename"] == file_to_edit_path:
|
641 |
block["code"] = edited_content
|
|
|
645 |
found_in_cache = True
|
646 |
break
|
647 |
if not found_in_cache:
|
648 |
+
# Assignment to global variable
|
649 |
parsed_code_blocks_state_cache = [b for b in parsed_code_blocks_state_cache if b["filename"] != file_to_edit_path]
|
650 |
parsed_code_blocks_state_cache.append({
|
651 |
"filename": file_to_edit_path,
|
|
|
654 |
"is_binary": False,
|
655 |
"is_structure_block": False
|
656 |
})
|
657 |
+
parsed_code_blocks_state_cache.sort(key=lambda b: (0, b["filename"]) if b.get("is_structure_block") else (1, b["filename"))
|
658 |
|
659 |
_formatted_md_out, _detected_preview_out, _download_btn_out = _generate_ui_outputs_from_cache(owner_to_use, ui_space_name_part)
|
660 |
|
|
|
704 |
new_file_list, err_list = list_space_files_for_browsing(hf_api_key_ui, ui_space_name_part, owner_to_use)
|
705 |
|
706 |
if "Successfully deleted" in deletion_status_msg:
|
707 |
+
# Assignment to global variable
|
708 |
parsed_code_blocks_state_cache = [b for b in parsed_code_blocks_state_cache if b["filename"] != file_to_delete_path]
|
709 |
_formatted_md_out, _detected_preview_out, _download_btn_out = _generate_ui_outputs_from_cache(owner_to_use, ui_space_name_part)
|
710 |
|
|
|
900 |
delete_file_outputs = [edit_status_display, file_browser_dropdown, file_browser_dropdown, file_content_editor, commit_message_input, file_content_editor, formatted_space_output_display, detected_files_preview, download_button]
|
901 |
delete_file_button.click(fn=handle_delete_file, inputs=[hf_api_key_input, space_name_input, owner_name_input, file_browser_dropdown], outputs=delete_file_outputs)
|
902 |
|
903 |
+
refresh_space_status_button.click(fn=handle_refresh_space_status, inputs=[hf_api_key_input, owner_name_input, space_name_input], outputs=[space_runtime_status_display])
|
904 |
|
905 |
if __name__ == "__main__":
|
906 |
demo.launch(debug=True, share=False)
|