naman1102 commited on
Commit
db1867d
Β·
1 Parent(s): 6b1539d
Files changed (2) hide show
  1. app.py +153 -22
  2. chatbot_page.py +8 -4
app.py CHANGED
@@ -422,8 +422,23 @@ def create_ui() -> gr.Blocks:
422
  transform: scale(1.02);
423
  }
424
 
425
- /* Remove hover effect from other cells */
426
- .gr-dataframe td:nth-child(n+2) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  cursor: default;
428
  }
429
 
@@ -554,6 +569,7 @@ def create_ui() -> gr.Blocks:
554
  with gr.Row():
555
  analyze_next_btn = gr.Button("⚑ Analyze Next Repository", variant="primary", size="lg", scale=1)
556
  analyze_all_btn = gr.Button("πŸš€ Analyze All Repositories", variant="secondary", size="lg", scale=1)
 
557
  with gr.Column(scale=2):
558
  status_box_analysis = gr.Textbox(label="πŸ“ˆ Analysis Status", interactive=False, lines=2)
559
 
@@ -599,6 +615,26 @@ def create_ui() -> gr.Blocks:
599
 
600
  gr.Markdown("πŸ’‘ **Tip:** Click on any repository name to explore it in detail!")
601
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  # Modal popup for repository action selection
603
  with gr.Row():
604
  with gr.Column():
@@ -802,14 +838,14 @@ def create_ui() -> gr.Blocks:
802
  status = "Status: Keywords extracted. User requirements saved for analysis."
803
  return final_keywords_str, status, user_requirements
804
 
805
- def handle_dataframe_select(evt: gr.SelectData, df_data) -> Tuple[str, Any, Any]:
806
- """Handle dataframe row selection - only repo ID column triggers modal."""
807
  print(f"DEBUG: Selection event triggered!")
808
  print(f"DEBUG: evt = {evt}")
809
  print(f"DEBUG: df_data type = {type(df_data)}")
810
 
811
  if evt is None:
812
- return "", gr.update(visible=False), gr.update()
813
 
814
  try:
815
  # Get the selected row and column from the event
@@ -817,23 +853,41 @@ def create_ui() -> gr.Blocks:
817
  col_idx = evt.index[1]
818
  print(f"DEBUG: Selected row {row_idx}, column {col_idx}")
819
 
820
- # Only respond to clicks on the repo ID column (column 0)
821
- if col_idx != 0:
822
- print(f"DEBUG: Clicked on column {col_idx}, ignoring (only repo ID column responds)")
823
- return "", gr.update(visible=False), gr.update()
824
-
825
  # Handle pandas DataFrame
826
  if isinstance(df_data, pd.DataFrame) and not df_data.empty and row_idx < len(df_data):
827
- # Get the repository ID from the first column
828
- repo_id = df_data.iloc[row_idx, 0] # First column contains repo id
829
- print(f"DEBUG: Extracted repo_id = '{repo_id}'")
830
 
831
- # Only proceed if we actually have a repository ID
832
- if repo_id and str(repo_id).strip() and str(repo_id).strip() != 'nan':
833
- clean_repo_id = str(repo_id).strip()
834
- logger.info(f"Showing modal for repository: {clean_repo_id}")
835
- # Show modal and populate selected repo
836
- return clean_repo_id, gr.update(visible=True), gr.update()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
837
  else:
838
  print(f"DEBUG: df_data is not a DataFrame or row_idx {row_idx} out of range")
839
 
@@ -841,7 +895,7 @@ def create_ui() -> gr.Blocks:
841
  print(f"DEBUG: Exception occurred: {e}")
842
  logger.error(f"Error handling dataframe selection: {e}")
843
 
844
- return "", gr.update(visible=False), gr.update()
845
 
846
  def handle_analyze_all_repos(repo_ids: List[str], user_requirements: str, progress=gr.Progress()) -> Tuple[pd.DataFrame, str, pd.DataFrame, Any]:
847
  """Analyzes all repositories in the CSV file with progress tracking."""
@@ -973,6 +1027,71 @@ def create_ui() -> gr.Blocks:
973
  """Handle closing the modal."""
974
  return gr.update(visible=False)
975
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
976
  # --- Component Event Wiring ---
977
 
978
  # Initialize chatbot with welcome message on app load
@@ -1062,18 +1181,30 @@ def create_ui() -> gr.Blocks:
1062
  outputs=[repo_action_modal]
1063
  )
1064
 
 
 
 
 
 
 
1065
  # Add dataframe selection event
1066
  df_output.select(
1067
  fn=handle_dataframe_select,
1068
  inputs=[df_output],
1069
- outputs=[selected_repo_display, repo_action_modal, tabs]
1070
  )
1071
 
1072
  # Add selection event for top repositories dataframe too
1073
  top_repos_df.select(
1074
  fn=handle_dataframe_select,
1075
  inputs=[top_repos_df],
1076
- outputs=[selected_repo_display, repo_action_modal, tabs]
 
 
 
 
 
 
1077
  )
1078
 
1079
  return app
 
422
  transform: scale(1.02);
423
  }
424
 
425
+ /* Make content columns (strengths, weaknesses, speciality) clickable for text expansion */
426
+ .gr-dataframe td:nth-child(2),
427
+ .gr-dataframe td:nth-child(3),
428
+ .gr-dataframe td:nth-child(4) {
429
+ cursor: pointer;
430
+ transition: all 0.3s ease;
431
+ }
432
+
433
+ .gr-dataframe td:nth-child(2):hover,
434
+ .gr-dataframe td:nth-child(3):hover,
435
+ .gr-dataframe td:nth-child(4):hover {
436
+ background-color: rgba(102, 126, 234, 0.08);
437
+ box-shadow: inset 0 0 0 1px rgba(102, 126, 234, 0.2);
438
+ }
439
+
440
+ /* Relevance column - not clickable */
441
+ .gr-dataframe td:nth-child(5) {
442
  cursor: default;
443
  }
444
 
 
569
  with gr.Row():
570
  analyze_next_btn = gr.Button("⚑ Analyze Next Repository", variant="primary", size="lg", scale=1)
571
  analyze_all_btn = gr.Button("πŸš€ Analyze All Repositories", variant="secondary", size="lg", scale=1)
572
+ reset_all_btn = gr.Button("πŸ”„ Reset Everything", variant="stop", size="lg", scale=1)
573
  with gr.Column(scale=2):
574
  status_box_analysis = gr.Textbox(label="πŸ“ˆ Analysis Status", interactive=False, lines=2)
575
 
 
615
 
616
  gr.Markdown("πŸ’‘ **Tip:** Click on any repository name to explore it in detail!")
617
 
618
+ # Text expansion modal for showing full content
619
+ with gr.Row():
620
+ with gr.Column():
621
+ text_expansion_modal = gr.Column(visible=False)
622
+ with text_expansion_modal:
623
+ gr.Markdown("### πŸ“„ Full Content View")
624
+ expanded_content_title = gr.Textbox(
625
+ label="Content Type",
626
+ interactive=False,
627
+ info="Full text content for the selected field"
628
+ )
629
+ expanded_content_text = gr.Textbox(
630
+ label="Full Text",
631
+ lines=10,
632
+ interactive=False,
633
+ show_copy_button=True,
634
+ info="Complete untruncated content"
635
+ )
636
+ close_text_modal_btn = gr.Button("❌ Close", size="lg")
637
+
638
  # Modal popup for repository action selection
639
  with gr.Row():
640
  with gr.Column():
 
838
  status = "Status: Keywords extracted. User requirements saved for analysis."
839
  return final_keywords_str, status, user_requirements
840
 
841
+ def handle_dataframe_select(evt: gr.SelectData, df_data) -> Tuple[str, Any, Any, str, str, Any]:
842
+ """Handle dataframe row selection - repo ID shows modal, content columns show full text."""
843
  print(f"DEBUG: Selection event triggered!")
844
  print(f"DEBUG: evt = {evt}")
845
  print(f"DEBUG: df_data type = {type(df_data)}")
846
 
847
  if evt is None:
848
+ return "", gr.update(visible=False), gr.update(), "", "", gr.update(visible=False)
849
 
850
  try:
851
  # Get the selected row and column from the event
 
853
  col_idx = evt.index[1]
854
  print(f"DEBUG: Selected row {row_idx}, column {col_idx}")
855
 
 
 
 
 
 
856
  # Handle pandas DataFrame
857
  if isinstance(df_data, pd.DataFrame) and not df_data.empty and row_idx < len(df_data):
 
 
 
858
 
859
+ # Column mapping: 0=repo, 1=strength, 2=weakness, 3=speciality, 4=relevance
860
+ if col_idx == 1: # Strengths column
861
+ full_text = str(df_data.iloc[row_idx, 1])
862
+ repo_name = str(df_data.iloc[row_idx, 0])
863
+ title = f"Strengths - {repo_name}"
864
+ return "", gr.update(visible=False), gr.update(), title, full_text, gr.update(visible=True)
865
+
866
+ elif col_idx == 2: # Weaknesses column
867
+ full_text = str(df_data.iloc[row_idx, 2])
868
+ repo_name = str(df_data.iloc[row_idx, 0])
869
+ title = f"Weaknesses - {repo_name}"
870
+ return "", gr.update(visible=False), gr.update(), title, full_text, gr.update(visible=True)
871
+
872
+ elif col_idx == 3: # Speciality column
873
+ full_text = str(df_data.iloc[row_idx, 3])
874
+ repo_name = str(df_data.iloc[row_idx, 0])
875
+ title = f"Speciality - {repo_name}"
876
+ return "", gr.update(visible=False), gr.update(), title, full_text, gr.update(visible=True)
877
+
878
+ elif col_idx == 0: # Repository name column - show action modal
879
+ repo_id = df_data.iloc[row_idx, 0]
880
+ print(f"DEBUG: Extracted repo_id = '{repo_id}'")
881
+
882
+ if repo_id and str(repo_id).strip() and str(repo_id).strip() != 'nan':
883
+ clean_repo_id = str(repo_id).strip()
884
+ logger.info(f"Showing modal for repository: {clean_repo_id}")
885
+ return clean_repo_id, gr.update(visible=True), gr.update(), "", "", gr.update(visible=False)
886
+
887
+ # For other columns (like relevance), do nothing
888
+ else:
889
+ print(f"DEBUG: Clicked on column {col_idx}, no action defined")
890
+ return "", gr.update(visible=False), gr.update(), "", "", gr.update(visible=False)
891
  else:
892
  print(f"DEBUG: df_data is not a DataFrame or row_idx {row_idx} out of range")
893
 
 
895
  print(f"DEBUG: Exception occurred: {e}")
896
  logger.error(f"Error handling dataframe selection: {e}")
897
 
898
+ return "", gr.update(visible=False), gr.update(), "", "", gr.update(visible=False)
899
 
900
  def handle_analyze_all_repos(repo_ids: List[str], user_requirements: str, progress=gr.Progress()) -> Tuple[pd.DataFrame, str, pd.DataFrame, Any]:
901
  """Analyzes all repositories in the CSV file with progress tracking."""
 
1027
  """Handle closing the modal."""
1028
  return gr.update(visible=False)
1029
 
1030
+ def handle_close_text_modal() -> Any:
1031
+ """Handle closing the text expansion modal."""
1032
+ return gr.update(visible=False)
1033
+
1034
+ def handle_reset_everything() -> Tuple[List[str], int, str, pd.DataFrame, pd.DataFrame, Any, Any, Any, List[Dict[str, str]], str, str, str]:
1035
+ """Reset everything to initial state - clear all data, CSV, and UI components."""
1036
+ try:
1037
+ # Clear the CSV file
1038
+ if os.path.exists(CSV_FILE):
1039
+ os.remove(CSV_FILE)
1040
+ logger.info("CSV file deleted for reset")
1041
+
1042
+ # Create empty dataframe
1043
+ empty_df = pd.DataFrame(columns=["repo id", "strength", "weaknesses", "speciality", "relevance rating"])
1044
+
1045
+ # Reset state variables
1046
+ repo_ids_reset = []
1047
+ current_idx_reset = 0
1048
+ user_requirements_reset = ""
1049
+
1050
+ # Reset status
1051
+ status_reset = "Status: Everything has been reset. Ready to start fresh!"
1052
+
1053
+ # Reset UI components
1054
+ current_requirements_reset = "No requirements extracted yet."
1055
+ extracted_keywords_reset = ""
1056
+
1057
+ # Reset chatbot to initial message
1058
+ chatbot_reset = [{"role": "assistant", "content": CHATBOT_INITIAL_MESSAGE}]
1059
+
1060
+ logger.info("Complete system reset performed")
1061
+
1062
+ return (
1063
+ repo_ids_reset, # repo_ids_state
1064
+ current_idx_reset, # current_repo_idx_state
1065
+ user_requirements_reset, # user_requirements_state
1066
+ empty_df, # df_output
1067
+ empty_df, # top_repos_df
1068
+ gr.update(visible=False), # top_repos_section
1069
+ gr.update(visible=False), # repo_action_modal
1070
+ gr.update(visible=False), # text_expansion_modal
1071
+ chatbot_reset, # chatbot
1072
+ status_reset, # status_box_analysis
1073
+ current_requirements_reset, # current_requirements_display
1074
+ extracted_keywords_reset # extracted_keywords_output
1075
+ )
1076
+
1077
+ except Exception as e:
1078
+ logger.error(f"Error during reset: {e}")
1079
+ error_status = f"Reset failed: {e}"
1080
+ return (
1081
+ [], # repo_ids_state
1082
+ 0, # current_repo_idx_state
1083
+ "", # user_requirements_state
1084
+ pd.DataFrame(), # df_output
1085
+ pd.DataFrame(), # top_repos_df
1086
+ gr.update(visible=False), # top_repos_section
1087
+ gr.update(visible=False), # repo_action_modal
1088
+ gr.update(visible=False), # text_expansion_modal
1089
+ [{"role": "assistant", "content": CHATBOT_INITIAL_MESSAGE}], # chatbot
1090
+ error_status, # status_box_analysis
1091
+ "No requirements extracted yet.", # current_requirements_display
1092
+ "" # extracted_keywords_output
1093
+ )
1094
+
1095
  # --- Component Event Wiring ---
1096
 
1097
  # Initialize chatbot with welcome message on app load
 
1181
  outputs=[repo_action_modal]
1182
  )
1183
 
1184
+ # Text expansion modal events
1185
+ close_text_modal_btn.click(
1186
+ fn=handle_close_text_modal,
1187
+ outputs=[text_expansion_modal]
1188
+ )
1189
+
1190
  # Add dataframe selection event
1191
  df_output.select(
1192
  fn=handle_dataframe_select,
1193
  inputs=[df_output],
1194
+ outputs=[selected_repo_display, repo_action_modal, tabs, expanded_content_title, expanded_content_text, text_expansion_modal]
1195
  )
1196
 
1197
  # Add selection event for top repositories dataframe too
1198
  top_repos_df.select(
1199
  fn=handle_dataframe_select,
1200
  inputs=[top_repos_df],
1201
+ outputs=[selected_repo_display, repo_action_modal, tabs, expanded_content_title, expanded_content_text, text_expansion_modal]
1202
+ )
1203
+
1204
+ # Reset button event
1205
+ reset_all_btn.click(
1206
+ fn=handle_reset_everything,
1207
+ outputs=[repo_ids_state, current_repo_idx_state, user_requirements_state, df_output, top_repos_df, top_repos_section, repo_action_modal, text_expansion_modal, chatbot, status_box_analysis, current_requirements_display, extracted_keywords_output]
1208
  )
1209
 
1210
  return app
chatbot_page.py CHANGED
@@ -4,9 +4,11 @@ import os
4
 
5
  # System prompt for the chatbot
6
  CHATBOT_SYSTEM_PROMPT = (
7
- "You are a helpful and friendly assistant. Your goal is to help the user discover their ideal Hugging Face repository. "
8
- "Engage in a natural conversation, ask clarifying questions about their needs, such as their use case, preferred programming languages, or specific features they are looking for. "
9
  "Keep your responses concise and focused on helping the user."
 
 
10
  )
11
 
12
  # Store the conversation
@@ -44,10 +46,12 @@ def extract_keywords_from_conversation(history):
44
  # Combine all user and assistant messages into a single string
45
  conversation = "\n".join([f"User: {msg[0]}\nAssistant: {msg[1]}" for msg in history if msg[1]])
46
  system_prompt = (
47
- "You are an expert at helping users find open-source repos on Hugging Face. "
48
- "Given a conversation, extract about 5 keywords that would be most useful for searching Hugging Face repos to find the most relevant results for the user. "
49
  "Return only the keywords as a comma-separated list."
50
  "Use keywords that are specific to the user's use case and features they are looking for."
 
 
51
  )
52
  user_prompt = (
53
  "Conversation:\n" + conversation + "\n\nExtract about 5 keywords for Hugging Face repo search."
 
4
 
5
  # System prompt for the chatbot
6
  CHATBOT_SYSTEM_PROMPT = (
7
+ "Your goal is to undertsand what the user needs in their ideal Hugging Face repository. Specifically a Hugging Face Space. "
8
+ "Engage in a natural conversation, ask clarifying questions about their needs, such as their use case or specific features they are looking for. "
9
  "Keep your responses concise and focused on helping the user."
10
+ "When you feel you have gathered enough detailed information about their requirements, ask the user to end chat."
11
+
12
  )
13
 
14
  # Store the conversation
 
46
  # Combine all user and assistant messages into a single string
47
  conversation = "\n".join([f"User: {msg[0]}\nAssistant: {msg[1]}" for msg in history if msg[1]])
48
  system_prompt = (
49
+ "You are an expert at helping find Hugging Face Spaces. You must look at the conversation carefully."
50
+ "Given a conversation, extract about 5 keywords that would be most useful for searching Hugging Face Spaces.. "
51
  "Return only the keywords as a comma-separated list."
52
  "Use keywords that are specific to the user's use case and features they are looking for."
53
+ "Dont use very generic search words like programming, language, hugging face, ML, AI, etc."
54
+
55
  )
56
  user_prompt = (
57
  "Conversation:\n" + conversation + "\n\nExtract about 5 keywords for Hugging Face repo search."