Update app.py
Browse files
app.py
CHANGED
@@ -632,6 +632,7 @@ def create_ui() -> gr.Blocks:
|
|
632 |
value=True,
|
633 |
info="Automatically start analysis when repositories are found"
|
634 |
)
|
|
|
635 |
|
636 |
status_box_input = gr.Textbox(label="π Status", interactive=False, lines=2)
|
637 |
|
@@ -704,6 +705,9 @@ def create_ui() -> gr.Blocks:
|
|
704 |
)
|
705 |
send_btn = gr.Button("π€", variant="primary", scale=1)
|
706 |
|
|
|
|
|
|
|
707 |
# Status and extracted info (auto-updated, no manual buttons needed)
|
708 |
with gr.Row():
|
709 |
with gr.Column():
|
@@ -857,6 +861,58 @@ def create_ui() -> gr.Blocks:
|
|
857 |
|
858 |
return ""
|
859 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
def extract_user_requirements_from_chat(history: List[Dict[str, str]]) -> str:
|
861 |
"""Extract user requirements from chatbot conversation."""
|
862 |
if not history:
|
@@ -1071,6 +1127,18 @@ def create_ui() -> gr.Blocks:
|
|
1071 |
outputs=[df_output, status_box_input, top_repos_df, top_repos_section]
|
1072 |
)
|
1073 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1074 |
# Auto-analyze checkbox toggle
|
1075 |
auto_analyze_checkbox.change(
|
1076 |
fn=handle_auto_analyze_toggle,
|
@@ -1126,6 +1194,18 @@ def create_ui() -> gr.Blocks:
|
|
1126 |
outputs=[df_output, chat_status, top_repos_df, top_repos_section]
|
1127 |
)
|
1128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1129 |
# Repo Explorer Tab
|
1130 |
setup_repo_explorer_events(repo_components, repo_states)
|
1131 |
|
|
|
632 |
value=True,
|
633 |
info="Automatically start analysis when repositories are found"
|
634 |
)
|
635 |
+
smart_submit_btn = gr.Button("π Find & Process Repositories", variant="primary", size="lg", scale=1)
|
636 |
|
637 |
status_box_input = gr.Textbox(label="π Status", interactive=False, lines=2)
|
638 |
|
|
|
705 |
)
|
706 |
send_btn = gr.Button("π€", variant="primary", scale=1)
|
707 |
|
708 |
+
with gr.Row():
|
709 |
+
extract_analyze_btn = gr.Button("π― Extract Keywords & Analyze Now", variant="secondary", size="lg")
|
710 |
+
|
711 |
# Status and extracted info (auto-updated, no manual buttons needed)
|
712 |
with gr.Row():
|
713 |
with gr.Column():
|
|
|
861 |
|
862 |
return ""
|
863 |
|
864 |
+
def handle_extract_and_analyze(history: List[Dict[str, str]]) -> Tuple[str, str, str, List[str], int, pd.DataFrame, Any, pd.DataFrame, str, Any]:
|
865 |
+
"""Extract keywords from chat, search repositories, and immediately start analysis."""
|
866 |
+
if not history:
|
867 |
+
return "β No conversation to extract from.", "", "", [], 0, pd.DataFrame(), gr.update(), pd.DataFrame(), "", gr.update(visible=False)
|
868 |
+
|
869 |
+
# Convert the full, valid history for the extraction logic
|
870 |
+
tuple_history = convert_messages_to_tuples(history)
|
871 |
+
if not tuple_history:
|
872 |
+
return "β No completed conversations to analyze.", "", "", [], 0, pd.DataFrame(), gr.update(), pd.DataFrame(), "", gr.update(visible=False)
|
873 |
+
|
874 |
+
# Get raw keywords string from the LLM
|
875 |
+
raw_keywords_str = extract_keywords_from_conversation(tuple_history)
|
876 |
+
|
877 |
+
# Sanitize the LLM output to extract only keyword-like parts
|
878 |
+
cleaned_keywords = re.findall(r'[\w\s-]+', raw_keywords_str)
|
879 |
+
cleaned_keywords = [kw.strip() for kw in cleaned_keywords if kw.strip()]
|
880 |
+
|
881 |
+
if not cleaned_keywords:
|
882 |
+
return f"β Could not extract valid keywords. Raw output: '{raw_keywords_str}'", "", "", [], 0, pd.DataFrame(), gr.update(), pd.DataFrame(), "", gr.update(visible=False)
|
883 |
+
|
884 |
+
# Join them into a clean, comma-separated string
|
885 |
+
final_keywords_str = ", ".join(cleaned_keywords)
|
886 |
+
|
887 |
+
# Extract user requirements for analysis
|
888 |
+
user_requirements = extract_user_requirements_from_chat(history)
|
889 |
+
|
890 |
+
# Auto-search repositories
|
891 |
+
repo_ids = []
|
892 |
+
for kw in cleaned_keywords[:3]: # Use top 3 keywords to avoid too many results
|
893 |
+
repo_ids.extend(search_top_spaces(kw, limit=5))
|
894 |
+
|
895 |
+
unique_repo_ids = list(dict.fromkeys(repo_ids))
|
896 |
+
|
897 |
+
if not unique_repo_ids:
|
898 |
+
return f"β No repositories found for keywords: {final_keywords_str}", final_keywords_str, user_requirements, [], 0, pd.DataFrame(), gr.update(), pd.DataFrame(), "", gr.update(visible=False)
|
899 |
+
|
900 |
+
write_repos_to_csv(unique_repo_ids)
|
901 |
+
df = format_dataframe_for_display(read_csv_to_dataframe())
|
902 |
+
|
903 |
+
# Immediately start analysis
|
904 |
+
try:
|
905 |
+
analyzed_df, analysis_status, top_repos, top_section_update = handle_analyze_all_repos(unique_repo_ids, user_requirements)
|
906 |
+
|
907 |
+
chat_status = f"π Extracted keywords β Found {len(unique_repo_ids)} repositories β Analysis complete!"
|
908 |
+
|
909 |
+
return chat_status, final_keywords_str, user_requirements, unique_repo_ids, 0, analyzed_df, gr.update(selected="analysis_tab"), top_repos, analysis_status, top_section_update
|
910 |
+
|
911 |
+
except Exception as e:
|
912 |
+
logger.error(f"Error during extract and analyze: {e}")
|
913 |
+
error_status = f"β
Found {len(unique_repo_ids)} repositories, but analysis failed: {e}"
|
914 |
+
return error_status, final_keywords_str, user_requirements, unique_repo_ids, 0, df, gr.update(selected="analysis_tab"), pd.DataFrame(), "", gr.update(visible=False)
|
915 |
+
|
916 |
def extract_user_requirements_from_chat(history: List[Dict[str, str]]) -> str:
|
917 |
"""Extract user requirements from chatbot conversation."""
|
918 |
if not history:
|
|
|
1127 |
outputs=[df_output, status_box_input, top_repos_df, top_repos_section]
|
1128 |
)
|
1129 |
|
1130 |
+
# Smart Submit Button (same behavior as enter)
|
1131 |
+
smart_submit_btn.click(
|
1132 |
+
fn=handle_smart_input,
|
1133 |
+
inputs=[smart_input, auto_analyze_checkbox],
|
1134 |
+
outputs=[repo_ids_state, current_repo_idx_state, df_output, status_box_input, tabs, status_box_input]
|
1135 |
+
).then(
|
1136 |
+
# If auto_analyze is enabled and we got repos, start analysis automatically
|
1137 |
+
fn=lambda repo_ids, user_reqs, trigger: handle_analyze_all_repos(repo_ids, user_reqs) if trigger == "auto_analyze" and repo_ids else (pd.DataFrame(), "Ready for analysis.", pd.DataFrame(), gr.update(visible=False)),
|
1138 |
+
inputs=[repo_ids_state, user_requirements_state, status_box_input],
|
1139 |
+
outputs=[df_output, status_box_input, top_repos_df, top_repos_section]
|
1140 |
+
)
|
1141 |
+
|
1142 |
# Auto-analyze checkbox toggle
|
1143 |
auto_analyze_checkbox.change(
|
1144 |
fn=handle_auto_analyze_toggle,
|
|
|
1194 |
outputs=[df_output, chat_status, top_repos_df, top_repos_section]
|
1195 |
)
|
1196 |
|
1197 |
+
# Extract and Analyze Button (one-click solution for chatbot)
|
1198 |
+
extract_analyze_btn.click(
|
1199 |
+
fn=handle_extract_and_analyze,
|
1200 |
+
inputs=[chatbot],
|
1201 |
+
outputs=[chat_status, extracted_keywords_output, user_requirements_state, repo_ids_state, current_repo_idx_state, df_output, tabs, top_repos_df, status_box_analysis, top_repos_section]
|
1202 |
+
).then(
|
1203 |
+
# Update requirements display when they change
|
1204 |
+
fn=lambda req: req if req.strip() else "No specific requirements extracted from conversation.",
|
1205 |
+
inputs=[user_requirements_state],
|
1206 |
+
outputs=[current_requirements_display]
|
1207 |
+
)
|
1208 |
+
|
1209 |
# Repo Explorer Tab
|
1210 |
setup_repo_explorer_events(repo_components, repo_states)
|
1211 |
|