mdabidhussain commited on
Commit
8455de3
Β·
1 Parent(s): 062db00

updated doc-mcp app

Browse files
Files changed (2) hide show
  1. app.py +103 -34
  2. rag/query.py +0 -2
app.py CHANGED
@@ -791,74 +791,125 @@ with gr.Blocks(title="Doc-MCP") as demo:
791
 
792
  with gr.Row():
793
  with gr.Column(scale=2):
794
- # Repository selection
795
- repo_dropdown = gr.Dropdown(
796
- choices=get_available_repositories(),
797
- label="Select Documentation Repository",
798
- value=None,
799
- interactive=True,
800
- allow_custom_value=False,
801
- )
 
 
 
 
 
 
 
 
 
 
 
 
802
  refresh_repos_btn = gr.Button(
803
- "πŸ”„ Refresh Repositories", variant="secondary", size="sm"
804
  )
805
 
806
  # Query mode selection
807
  query_mode = gr.Radio(
808
  choices=["default", "text_search", "hybrid"],
809
- label="Query Mode",
810
  value="default",
811
- info="default: semantic similarity, text_search: keyword-based, hybrid: combines both",
812
  )
813
 
814
  # Query input
815
  query_input = gr.Textbox(
816
- label="Your Query",
817
- placeholder="Ask about the documentation...",
818
  lines=3,
 
819
  )
820
 
821
- query_btn = gr.Button("πŸ” Search", variant="primary", size="lg")
822
 
823
  # Response display as text area
824
  response_output = gr.Textbox(
825
- label="Response",
826
- value="Your query response will appear here...",
827
  lines=10,
828
  interactive=False,
 
829
  )
830
 
831
  with gr.Column(scale=2):
832
- gr.Markdown("### Source Nodes (JSON)")
 
833
 
834
  # Source nodes display as JSON
835
  sources_output = gr.JSON(
836
- label="Source Nodes",
837
  value={
838
- "message": "Source nodes will appear here after querying..."
 
839
  },
840
  )
841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  def get_available_docs_repo():
843
  """
844
- List the available docs of repositories
845
 
846
  Returns:
847
- List of repo names
848
  """
849
  try:
850
  repos = get_available_repositories()
851
- return gr.Dropdown(choices=repos, value=repos[0] if repos else None)
 
 
852
  except Exception as e:
853
  print(f"Error refreshing repository list: {e}")
854
- return gr.Dropdown(choices=[], value=None)
855
 
856
  # Simple query handler
857
  def handle_query(repo: str, mode: str, query: str):
858
  """
859
  Handle query request - returns raw data from retriever
860
  Args:
861
- repo: Selected repository
862
  mode: Query mode (default, text_search, hybrid)
863
  query: User's query
864
  Returns:
@@ -867,8 +918,8 @@ with gr.Blocks(title="Doc-MCP") as demo:
867
  if not query.strip():
868
  return {"error": "Please enter a query."}
869
 
870
- if not repo:
871
- return {"error": "Please select a repository."}
872
 
873
  try:
874
  # Import QueryRetriever here to avoid circular imports
@@ -895,8 +946,8 @@ with gr.Blocks(title="Doc-MCP") as demo:
895
  This function is designed to support Retrieval-Augmented Generation (RAG) by extracting
896
  the most relevant context chunks from indexed documentation sources.
897
  Args:
898
- repo: Selected repository
899
- mode: Query mode
900
  query: User's query
901
  Returns:
902
  Tuple of (response_text, source_nodes_json)
@@ -914,24 +965,42 @@ with gr.Blocks(title="Doc-MCP") as demo:
914
 
915
  return response_text, source_nodes
916
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
917
  refresh_repos_btn.click(
918
  fn=get_available_docs_repo,
919
  outputs=[repo_dropdown],
920
- api_name="List available docs",
921
  )
922
 
923
- # Simple event wiring - single button click
924
  query_btn.click(
925
  fn=make_query,
926
- inputs=[repo_dropdown, query_mode, query_input],
927
  outputs=[response_output, sources_output],
928
- api_name="Query docs",
929
  )
930
 
931
  # Also allow Enter key to trigger query
932
  query_input.submit(
933
  fn=make_query,
934
- inputs=[repo_dropdown, query_mode, query_input],
935
  outputs=[response_output, sources_output],
936
  show_api=False,
937
  )
@@ -1149,4 +1218,4 @@ with gr.Blocks(title="Doc-MCP") as demo:
1149
 
1150
 
1151
  if __name__ == "__main__":
1152
- demo.launch(mcp_server=True, share=True)
 
791
 
792
  with gr.Row():
793
  with gr.Column(scale=2):
794
+ # Repository selection - Dropdown that becomes textbox when selected
795
+ with gr.Row():
796
+ repo_dropdown = gr.Dropdown(
797
+ choices=get_available_repositories() or ["No repositories available"],
798
+ label="πŸ“š Select Documentation Repository",
799
+ value=None,
800
+ interactive=True,
801
+ allow_custom_value=True,
802
+ info="Choose from available repositories"
803
+ )
804
+
805
+ # Hidden textbox that will become visible when repo is selected
806
+ selected_repo_textbox = gr.Textbox(
807
+ label="🎯 Selected Repository",
808
+ value="",
809
+ interactive=False,
810
+ visible=False,
811
+ info="Currently selected repository for querying"
812
+ )
813
+
814
  refresh_repos_btn = gr.Button(
815
+ "πŸ”„ Refresh Repository List", variant="secondary", size="sm"
816
  )
817
 
818
  # Query mode selection
819
  query_mode = gr.Radio(
820
  choices=["default", "text_search", "hybrid"],
821
+ label="πŸ” Search Strategy",
822
  value="default",
823
+ info="β€’ default: Semantic similarity (AI understanding)\nβ€’ text_search: Keyword matching\nβ€’ hybrid: Combined approach for best results",
824
  )
825
 
826
  # Query input
827
  query_input = gr.Textbox(
828
+ label="πŸ’­ Ask About Your Documentation",
829
+ placeholder="How do I implement a custom component? What are the available API endpoints? How to configure the system?",
830
  lines=3,
831
+ info="Ask natural language questions about your documentation"
832
  )
833
 
834
+ query_btn = gr.Button("πŸš€ Search Documentation", variant="primary", size="lg")
835
 
836
  # Response display as text area
837
  response_output = gr.Textbox(
838
+ label="πŸ€– AI Assistant Response",
839
+ value="Your AI-powered documentation response will appear here with contextual information and source citations...",
840
  lines=10,
841
  interactive=False,
842
+ info="Generated using Nebius LLM with retrieved documentation context"
843
  )
844
 
845
  with gr.Column(scale=2):
846
+ gr.Markdown("### πŸ“– Source References")
847
+ gr.Markdown("View the exact documentation sources used to generate the response, with relevance scores and GitHub links.")
848
 
849
  # Source nodes display as JSON
850
  sources_output = gr.JSON(
851
+ label="πŸ“Ž Source Citations & Metadata",
852
  value={
853
+ "message": "Source documentation excerpts with relevance scores will appear here after your query...",
854
+ "info": "Each source includes file path, relevance score, and content snippet"
855
  },
856
  )
857
 
858
+ # Event handlers
859
+ def handle_repo_selection(selected_repo):
860
+ """Handle repository selection from dropdown"""
861
+ if not selected_repo or selected_repo in ["No repositories available", ""]:
862
+ return (
863
+ gr.Dropdown(visible=True), # Keep dropdown visible
864
+ gr.Textbox(visible=False, value=""), # Hide textbox
865
+ gr.Button(interactive=False) # Disable query button
866
+ )
867
+ else:
868
+ return (
869
+ gr.Dropdown(visible=False), # Hide dropdown
870
+ gr.Textbox(visible=True, value=selected_repo), # Show textbox with selected repo
871
+ gr.Button(interactive=True) # Enable query button
872
+ )
873
+
874
+ def reset_repo_selection():
875
+ """Reset to show dropdown again"""
876
+ try:
877
+ repos = get_available_repositories() or ["No repositories available"]
878
+ return (
879
+ gr.Dropdown(choices=repos, value=None, visible=True), # Show dropdown with refreshed choices
880
+ gr.Textbox(visible=False, value=""), # Hide textbox
881
+ gr.Button(interactive=False) # Disable query button
882
+ )
883
+ except Exception as e:
884
+ print(f"Error refreshing repository list: {e}")
885
+ return (
886
+ gr.Dropdown(choices=["Error loading repositories"], value=None, visible=True),
887
+ gr.Textbox(visible=False, value=""),
888
+ gr.Button(interactive=False)
889
+ )
890
+
891
  def get_available_docs_repo():
892
  """
893
+ List the available docs of repositories - should be called first to list out all the available repo docs to chat with
894
 
895
  Returns:
896
+ Updated dropdown with available repositories
897
  """
898
  try:
899
  repos = get_available_repositories()
900
+ if not repos:
901
+ repos = ["No repositories available - Please ingest documentation first"]
902
+ return gr.Dropdown(choices=repos, value=None)
903
  except Exception as e:
904
  print(f"Error refreshing repository list: {e}")
905
+ return gr.Dropdown(choices=["Error loading repositories"], value=None)
906
 
907
  # Simple query handler
908
  def handle_query(repo: str, mode: str, query: str):
909
  """
910
  Handle query request - returns raw data from retriever
911
  Args:
912
+ repo: Selected repository from textbox
913
  mode: Query mode (default, text_search, hybrid)
914
  query: User's query
915
  Returns:
 
918
  if not query.strip():
919
  return {"error": "Please enter a query."}
920
 
921
+ if not repo or repo in ["No repositories available", "Error loading repositories", ""]:
922
+ return {"error": "Please select a valid repository."}
923
 
924
  try:
925
  # Import QueryRetriever here to avoid circular imports
 
946
  This function is designed to support Retrieval-Augmented Generation (RAG) by extracting
947
  the most relevant context chunks from indexed documentation sources.
948
  Args:
949
+ repo: Selected repository from the textbox input
950
+ mode: Query mode (default, text_search, hybrid)
951
  query: User's query
952
  Returns:
953
  Tuple of (response_text, source_nodes_json)
 
965
 
966
  return response_text, source_nodes
967
 
968
+ # Wire up events
969
+
970
+ # Handle repository selection from dropdown
971
+ repo_dropdown.change(
972
+ fn=handle_repo_selection,
973
+ inputs=[repo_dropdown],
974
+ outputs=[repo_dropdown, selected_repo_textbox, query_btn],
975
+ show_api=False
976
+ )
977
+
978
+ # Handle refresh button - resets to dropdown view
979
+ refresh_repos_btn.click(
980
+ fn=reset_repo_selection,
981
+ outputs=[repo_dropdown, selected_repo_textbox, query_btn],
982
+ show_api=False
983
+ )
984
+
985
+ # Also provide API endpoint for listing repositories
986
  refresh_repos_btn.click(
987
  fn=get_available_docs_repo,
988
  outputs=[repo_dropdown],
989
+ api_name="list_available_docs",
990
  )
991
 
992
+ # Query button uses the textbox value (not dropdown)
993
  query_btn.click(
994
  fn=make_query,
995
+ inputs=[selected_repo_textbox, query_mode, query_input], # Use textbox, not dropdown
996
  outputs=[response_output, sources_output],
997
+ api_name="query_documentation",
998
  )
999
 
1000
  # Also allow Enter key to trigger query
1001
  query_input.submit(
1002
  fn=make_query,
1003
+ inputs=[selected_repo_textbox, query_mode, query_input], # Use textbox, not dropdown
1004
  outputs=[response_output, sources_output],
1005
  show_api=False,
1006
  )
 
1218
 
1219
 
1220
  if __name__ == "__main__":
1221
+ demo.launch(mcp_server=True)
rag/query.py CHANGED
@@ -60,8 +60,6 @@ class QueryRetriever:
60
  response_mode="refine",
61
  )
62
 
63
-
64
-
65
  response = query_engine.query(query)
66
  nodes = []
67
  for node in response.source_nodes:
 
60
  response_mode="refine",
61
  )
62
 
 
 
63
  response = query_engine.query(query)
64
  nodes = []
65
  for node in response.source_nodes: