jzou19950715 commited on
Commit
9f9e972
·
verified ·
1 Parent(s): fc897ee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -94
app.py CHANGED
@@ -768,103 +768,20 @@ def get_db_stats(vector_store: VectorStoreManager) -> str:
768
  # The error occurs because there's likely a `try` statement without a matching `except` or `finally`
769
  # Here are the possible locations and fixes:
770
 
771
- # Option 1: If it's in the custom CSS definition around that line number
772
- custom_css = """
773
- .gradio-container {
774
- max-width: 1200px;
775
- margin: auto;
776
- }
777
- .gr-prose h1 {
778
- font-size: 2.5rem;
779
- margin-bottom: 1rem;
780
- color: #1a5276;
781
- }
782
- .gr-prose h3 {
783
- font-size: 1.25rem;
784
- font-weight: 600;
785
- margin-top: 1rem;
786
- margin-bottom: 0.5rem;
787
- color: #2874a6;
788
- }
789
- .container {
790
- margin: 0 auto;
791
- padding: 2rem;
792
- }
793
- .gr-box {
794
- border-radius: 8px;
795
- box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
796
- padding: 1rem;
797
- margin-bottom: 1rem;
798
- background-color: #f9f9f9;
799
- }
800
- .footer {
801
- text-align: center;
802
- font-size: 0.8rem;
803
- color: #666;
804
- margin-top: 2rem;
805
- }
806
- """ # Make sure this closing triple quote is present
807
 
808
- # Option 2: If it's in the main function, make sure all try blocks have matching except clauses
809
- def main():
810
- """Main function to run the RAG application"""
811
- # Path for configuration file
812
- CONFIG_FILE_PATH = "rag_config.json"
813
-
814
- # Try to load configuration from file, or use defaults
815
- if os.path.exists(CONFIG_FILE_PATH):
816
- config = Config.from_file(CONFIG_FILE_PATH)
817
- else:
818
- config = Config(
819
- local_dir="./chroma_db", # Store Chroma files in dedicated directory
820
- collection_name="markdown_docs"
821
- )
822
- # Save default configuration
823
- config.save_to_file(CONFIG_FILE_PATH)
824
-
825
- print(f"Starting Document Knowledge Assistant v{VERSION}")
826
- print(f"Log file: {log_file}")
827
-
828
- try:
829
- # Initialize vector store manager with existing collection
830
- vector_store = VectorStoreManager(config)
831
-
832
- # Initialize RAG system without API keys initially
833
- rag_system = RAGSystem(vector_store, config)
834
-
835
- # Create the Gradio interface with custom CSS
836
- with gr.Blocks(title="Document Knowledge Assistant", css=custom_css) as app:
837
- # Interface code here...
838
- pass # Replace with actual UI code
839
-
840
- # Launch the interface
841
- app.launch(
842
- share=False,
843
- server_name="0.0.0.0",
844
- server_port=7860,
845
- debug=False
846
- )
847
-
848
- except Exception as e: # Make sure there's an except clause for every try
849
- logger.critical(f"Error starting application: {e}")
850
- print(f"Error starting application: {e}")
851
- sys.exit(1)
852
 
853
- # Option 3: If it's in an Example or Markdown section, make sure triple quotes are properly closed
854
-
855
- # Option 4: Complete fix for the most likely scenario - an incomplete try block in the main function
856
- def main_fixed():
857
  """Main function to run the RAG application"""
858
  # Path for configuration file
859
  CONFIG_FILE_PATH = "rag_config.json"
860
 
861
- # Try to load configuration from file, or use defaults
862
  try:
 
863
  if os.path.exists(CONFIG_FILE_PATH):
864
  config = Config.from_file(CONFIG_FILE_PATH)
865
  else:
866
  config = Config(
867
- local_dir="./chroma_db",
868
  collection_name="markdown_docs"
869
  )
870
  # Save default configuration
@@ -879,17 +796,244 @@ def main_fixed():
879
  # Initialize RAG system without API keys initially
880
  rag_system = RAGSystem(vector_store, config)
881
 
882
- # Create the Gradio interface
883
  with gr.Blocks(title="Document Knowledge Assistant", css=custom_css) as app:
884
- # UI code here
885
- pass # Replace with actual UI code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886
 
887
- # Launch the interface
888
  app.launch(
889
- share=False,
890
- server_name="0.0.0.0",
891
- server_port=7860,
892
- debug=False
 
 
 
893
  )
894
  except Exception as e:
895
  logger.critical(f"Error starting application: {e}")
 
768
  # The error occurs because there's likely a `try` statement without a matching `except` or `finally`
769
  # Here are the possible locations and fixes:
770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
772
 
773
+ def main():
 
 
 
774
  """Main function to run the RAG application"""
775
  # Path for configuration file
776
  CONFIG_FILE_PATH = "rag_config.json"
777
 
 
778
  try:
779
+ # Try to load configuration from file, or use defaults
780
  if os.path.exists(CONFIG_FILE_PATH):
781
  config = Config.from_file(CONFIG_FILE_PATH)
782
  else:
783
  config = Config(
784
+ local_dir="./chroma_db", # Store Chroma files in dedicated directory
785
  collection_name="markdown_docs"
786
  )
787
  # Save default configuration
 
796
  # Initialize RAG system without API keys initially
797
  rag_system = RAGSystem(vector_store, config)
798
 
799
+ # Create the Gradio interface with custom CSS
800
  with gr.Blocks(title="Document Knowledge Assistant", css=custom_css) as app:
801
+ gr.Markdown(f"# Document Knowledge Assistant v{VERSION}")
802
+ gr.Markdown("Ask questions about your documents and get comprehensive AI-powered answers")
803
+
804
+ # Main layout
805
+ with gr.Row():
806
+ # Left column for asking questions
807
+ with gr.Column(scale=3):
808
+ with gr.Box():
809
+ gr.Markdown("### Ask Your Question")
810
+ query_input = gr.Textbox(
811
+ label="",
812
+ placeholder="What would you like to know about your documents?",
813
+ lines=3
814
+ )
815
+
816
+ with gr.Row():
817
+ query_button = gr.Button("Ask Question", variant="primary", scale=3)
818
+ clear_button = gr.Button("Clear", variant="secondary", scale=1)
819
+
820
+ with gr.Box():
821
+ gr.Markdown("### Answer")
822
+ response_output = gr.Markdown()
823
+
824
+ # Right column for settings
825
+ with gr.Column(scale=1):
826
+ # API Keys and model selection
827
+ with gr.Accordion("AI Model Settings", open=True):
828
+ gr.Markdown("### AI Configuration")
829
+ model_choice = gr.Radio(
830
+ choices=["openai", "gemini"],
831
+ value="openai",
832
+ label="AI Provider",
833
+ info=f"Select your preferred AI model"
834
+ )
835
+
836
+ api_key_input = gr.Textbox(
837
+ label="API Key",
838
+ placeholder="Enter your API key here...",
839
+ type="password",
840
+ info="Your key is not stored between sessions"
841
+ )
842
+
843
+ save_key_button = gr.Button("Save API Key", variant="primary")
844
+ api_status = gr.Markdown("")
845
+
846
+ # Advanced search controls
847
+ with gr.Accordion("Advanced Settings", open=False):
848
+ gr.Markdown("### Search & Response Settings")
849
+ num_results = gr.Slider(
850
+ minimum=3,
851
+ maximum=15,
852
+ value=config.default_top_k,
853
+ step=1,
854
+ label="Documents to search",
855
+ info="Higher values provide more context"
856
+ )
857
+
858
+ temperature_slider = gr.Slider(
859
+ minimum=0.0,
860
+ maximum=1.0,
861
+ value=config.temperature,
862
+ step=0.05,
863
+ label="Creativity",
864
+ info="Lower = more factual, Higher = more creative"
865
+ )
866
+
867
+ max_tokens_slider = gr.Slider(
868
+ minimum=500,
869
+ maximum=4000,
870
+ value=config.max_tokens,
871
+ step=100,
872
+ label="Response Length",
873
+ info="Maximum words in response"
874
+ )
875
+
876
+ # Database stats - simplified
877
+ with gr.Accordion("System Info", open=False):
878
+ stats_display = gr.Markdown(get_db_stats(vector_store))
879
+
880
+ gr.Markdown(f"""
881
+ **System Details:**
882
+ - Version: {VERSION}
883
+ - Embedding: {vector_store.embedding_engine.model_name}
884
+ - Device: {vector_store.embedding_engine.device}
885
+ """)
886
+ refresh_button = gr.Button("Refresh", variant="secondary", size="sm")
887
+
888
+ # Hidden element for search results (not visible to user)
889
+ with gr.Accordion("Debug Information", open=False, visible=False):
890
+ search_output = gr.Markdown()
891
+
892
+ # Query history at the bottom (optional section)
893
+ with gr.Accordion("Recent Questions", open=False):
894
+ history_list = gr.Dataframe(
895
+ headers=["Time", "Question", "Model"],
896
+ datatype=["str", "str", "str"],
897
+ row_count=5,
898
+ col_count=(3, "fixed"),
899
+ interactive=False
900
+ )
901
+
902
+ # Footer
903
+ gr.Markdown(
904
+ """<div class="footer">Document Knowledge Assistant helps you get insights from your documents using AI.
905
+ Powered by Retrieval Augmented Generation.</div>"""
906
+ )
907
+
908
+ # Query history storage
909
+ query_history = []
910
+
911
+ # Function to update API key based on selected model
912
+ def update_api_key(api_key, model):
913
+ if not api_key.strip():
914
+ return "❌ API key cannot be empty"
915
+
916
+ if model == "openai":
917
+ success = rag_system.setup_openai(api_key)
918
+ model_name = f"OpenAI {config.openai_model}"
919
+ else:
920
+ success = rag_system.setup_gemini(api_key)
921
+ model_name = f"Google {config.gemini_model}"
922
+
923
+ if success:
924
+ return f"✅ {model_name} connected successfully"
925
+ else:
926
+ return f"❌ Connection failed. Please check your API key and try again."
927
+
928
+ # Query function that returns both response and search results
929
+ def query_and_search(query, n_results, model, temperature, max_tokens):
930
+ # Update configuration with current UI values
931
+ config.temperature = float(temperature)
932
+ config.max_tokens = int(max_tokens)
933
+
934
+ start_time = datetime.now()
935
+
936
+ if not query.strip():
937
+ return "Please enter a question to get an answer.", "", query_history[-5:] if query_history else []
938
+
939
+ try:
940
+ # Verify that API keys are configured
941
+ if (model == "openai" and rag_system.openai_client is None) or \
942
+ (model == "gemini" and not rag_system.gemini_configured):
943
+ return "Please configure your API key first. Enter your API key in the settings panel and click 'Save API Key'.", "", query_history[-5:] if query_history else []
944
+
945
+ # Call the RAG system's query and generate function
946
+ response, search_output_text = rag_system.query_and_generate(
947
+ query=query,
948
+ n_results=int(n_results),
949
+ model=model
950
+ )
951
+
952
+ # Add to history
953
+ timestamp = datetime.now().strftime("%H:%M")
954
+ query_history.append([timestamp, query, model])
955
+
956
+ # Keep only the last 100 queries
957
+ if len(query_history) > 100:
958
+ query_history.pop(0)
959
+
960
+ # Update the history display with the most recent entries (reverse chronological)
961
+ recent_history = list(reversed(query_history[-5:])) if len(query_history) >= 5 else list(reversed(query_history))
962
+
963
+ # Calculate elapsed time
964
+ elapsed_time = (datetime.now() - start_time).total_seconds()
965
+
966
+ # Add subtle timing information to the response
967
+ response_with_timing = f"{response}\n\n<small>Answered in {elapsed_time:.1f}s</small>"
968
+
969
+ return response_with_timing, search_output_text, recent_history
970
+
971
+ except Exception as e:
972
+ error_msg = f"Error processing query: {str(e)}"
973
+ logger.error(error_msg)
974
+ logger.error(traceback.format_exc())
975
+ return "I encountered an error while processing your question. Please try again or check your API key settings.", "", query_history[-5:] if query_history else []
976
+
977
+ # Function to clear the input and results
978
+ def clear_inputs():
979
+ return "", "", "", query_history[-5:] if query_history else []
980
+
981
+ # Set up events
982
+ save_key_button.click(
983
+ fn=update_api_key,
984
+ inputs=[api_key_input, model_choice],
985
+ outputs=api_status
986
+ )
987
+
988
+ query_button.click(
989
+ fn=query_and_search,
990
+ inputs=[query_input, num_results, model_choice, temperature_slider, max_tokens_slider],
991
+ outputs=[response_output, search_output, history_list]
992
+ )
993
+
994
+ refresh_button.click(
995
+ fn=lambda: get_db_stats(vector_store),
996
+ inputs=None,
997
+ outputs=stats_display
998
+ )
999
+
1000
+ clear_button.click(
1001
+ fn=clear_inputs,
1002
+ inputs=None,
1003
+ outputs=[query_input, response_output, search_output, history_list]
1004
+ )
1005
+
1006
+ # Handle Enter key in query input
1007
+ query_input.submit(
1008
+ fn=query_and_search,
1009
+ inputs=[query_input, num_results, model_choice, temperature_slider, max_tokens_slider],
1010
+ outputs=[response_output, search_output, history_list]
1011
+ )
1012
+
1013
+ # Auto-fill examples
1014
+ examples = [
1015
+ ["What are the main features of this application?"],
1016
+ ["How does the retrieval augmented generation work?"],
1017
+ ["Can you explain the embedding models used in this system?"],
1018
+ ]
1019
+
1020
+ gr.Examples(
1021
+ examples=examples,
1022
+ inputs=query_input,
1023
+ outputs=[response_output, search_output, history_list],
1024
+ fn=lambda q: query_and_search(q, num_results.value, model_choice.value, temperature_slider.value, max_tokens_slider.value),
1025
+ cache_examples=False,
1026
+ )
1027
 
1028
+ # Launch the interface with a nice theme
1029
  app.launch(
1030
+ share=False, # Set to True to create a public link
1031
+ server_name="0.0.0.0", # Listen on all interfaces
1032
+ server_port=7860, # Default Gradio port
1033
+ debug=False, # Set to True during development
1034
+ auth=None, # Add (username, password) tuple for basic auth
1035
+ favicon_path="favicon.ico" if os.path.exists("favicon.ico") else None,
1036
+ show_error=True
1037
  )
1038
  except Exception as e:
1039
  logger.critical(f"Error starting application: {e}")