Shreyas094 commited on
Commit
66a2643
·
verified ·
1 Parent(s): 5e31c67

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -109
app.py CHANGED
@@ -28,9 +28,7 @@ llama_cloud_api_key = os.environ.get("LLAMA_CLOUD_API_KEY")
28
  ACCOUNT_ID = os.environ.get("CLOUDFARE_ACCOUNT_ID")
29
  API_TOKEN = os.environ.get("CLOUDFLARE_AUTH_TOKEN")
30
  API_BASE_URL = "https://api.cloudflare.com/client/v4/accounts/a17f03e0f049ccae0c15cdcf3b9737ce/ai/run/"
31
-
32
- # Add this to your existing imports and configurations
33
- whisper_client = InferenceClient("openai/whisper-large-v3", token=huggingface_token)
34
 
35
  print(f"ACCOUNT_ID: {ACCOUNT_ID}")
36
  print(f"CLOUDFLARE_AUTH_TOKEN: {API_TOKEN[:5]}..." if API_TOKEN else "Not set")
@@ -280,46 +278,21 @@ def generate_chunked_response(prompt, model, max_tokens=10000, num_calls=3, temp
280
  print(f"Final clean response: {final_response[:100]}...")
281
  return final_response
282
 
283
- def chatbot_interface(message, history, model, temperature, num_calls, use_web_search, selected_docs, audio):
 
 
 
 
 
284
  try:
285
- if not isinstance(history, list):
286
- history = []
287
-
288
- # Prioritize text input
289
- if message and isinstance(message, str) and message.strip():
290
- input_text = message.strip()
291
- elif audio is not None:
292
- # Only use audio if text input is empty and audio is provided
293
- transcribed_text = transcribe_audio(audio)
294
- if transcribed_text:
295
- input_text = transcribed_text
296
- else:
297
- return history # Return if both text and audio are empty
298
- else:
299
- return history # Return if both text and audio are empty
300
-
301
- # Add user message to history
302
- history.append((input_text, None))
303
-
304
- # Get response from the model
305
- response_generator = respond(input_text, history, model, temperature, num_calls, use_web_search, selected_docs)
306
-
307
- full_response = ""
308
- for partial_response in response_generator:
309
- full_response += str(partial_response)
310
- # Update the last message in history
311
- history[-1] = (input_text, full_response)
312
- yield history
313
-
314
- # If no response was generated, yield an error message
315
- if not full_response:
316
- history[-1] = (input_text, "I'm sorry, I couldn't generate a response. Please try again.")
317
  yield history
318
-
 
319
  except Exception as e:
320
- logging.error(f"Error in chatbot_interface: {str(e)}")
321
- error_message = f"An error occurred: {str(e)}"
322
- history.append((input_text if 'input_text' in locals() else "Error", error_message))
323
  yield history
324
 
325
  def retry_last_response(history, model, temperature, num_calls):
@@ -430,12 +403,13 @@ def respond(message, history, model, temperature, num_calls, use_web_search, sel
430
  logging.info(f"Model Used: {model}")
431
  logging.info(f"Selected Documents: {selected_docs}")
432
  logging.info(f"Use Web Search: {use_web_search}")
433
-
434
  if use_web_search:
435
  original_query = message
436
  rephrased_query = rephrase_query(message, conversation_manager)
437
  logging.info(f"Original query: {original_query}")
438
  logging.info(f"Rephrased query: {rephrased_query}")
 
439
  final_summary = ""
440
  for _ in range(num_calls):
441
  search_results = get_web_search_results(rephrased_query)
@@ -445,7 +419,8 @@ def respond(message, history, model, temperature, num_calls, use_web_search, sel
445
  final_summary += search_results[0]["error"] + "\n\n"
446
  else:
447
  summary = summarize_web_results(rephrased_query, search_results, conversation_manager)
448
- final_summary += str(summary) + "\n\n"
 
449
  if final_summary:
450
  conversation_manager.add_interaction(original_query, final_summary)
451
  yield final_summary
@@ -476,21 +451,21 @@ def respond(message, history, model, temperature, num_calls, use_web_search, sel
476
  if model.startswith("duckduckgo/"):
477
  # Use DuckDuckGo chat with context
478
  for partial_response in get_response_from_duckduckgo(message, model, context_str, num_calls, temperature):
479
- yield str(partial_response)
480
  elif model == "@cf/meta/llama-3.1-8b-instruct":
481
  # Use Cloudflare API
482
  for partial_response in get_response_from_cloudflare(prompt="", context=context_str, query=message, num_calls=num_calls, temperature=temperature, search_type="pdf"):
483
- yield str(partial_response)
484
  else:
485
  # Use Hugging Face API
486
  for partial_response in get_response_from_pdf(message, model, selected_docs, num_calls=num_calls, temperature=temperature):
487
- yield str(partial_response)
488
  except Exception as e:
489
  logging.error(f"Error with {model}: {str(e)}")
490
  if "microsoft/Phi-3-mini-4k-instruct" in model:
491
  logging.info("Falling back to Mistral model due to Phi-3 error")
492
  fallback_model = "mistralai/Mistral-7B-Instruct-v0.3"
493
- yield from (str(response) for response in respond(message, history, fallback_model, temperature, num_calls, selected_docs))
494
  else:
495
  yield f"An error occurred with the {model} model: {str(e)}. Please try again or select a different model."
496
 
@@ -632,28 +607,15 @@ Write a detailed and complete response that answers the following user question:
632
 
633
  logging.info("Finished generating response")
634
 
635
- def transcribe_audio(audio_file):
636
  if audio_file is None:
637
  return ""
638
 
639
- if isinstance(audio_file, list):
640
- if len(audio_file) == 0:
641
- return ""
642
- audio_file = audio_file[0] # Take the first element if it's a list
643
-
644
- if not isinstance(audio_file, (str, bytes, os.PathLike)):
645
- logging.error(f"Unexpected audio_file type: {type(audio_file)}")
646
- return f"Error: Unexpected audio file type {type(audio_file)}"
647
 
648
- try:
649
- with open(audio_file, "rb") as f:
650
- data = f.read()
651
-
652
- response = whisper_client.audio_to_text(data)
653
- return response["text"]
654
- except Exception as e:
655
- logging.error(f"Error transcribing audio: {str(e)}")
656
- return f"Error transcribing audio: {str(e)}"
657
 
658
  def vote(data: gr.LikeData):
659
  if data.liked:
@@ -704,42 +666,74 @@ use_web_search = gr.Checkbox(label="Use Web Search", value=False)
704
 
705
  custom_placeholder = "Ask a question (Note: You can toggle between Web Search and PDF Chat in Additional Inputs below)"
706
 
707
- # Update the demo interface
708
- # Update the Gradio interface
709
- demo = gr.ChatInterface(
710
- fn=chatbot_interface,
711
- additional_inputs_accordion=gr.Accordion(label="⚙️ Parameters", open=True, render=False),
712
- additional_inputs=[
713
- gr.Dropdown(choices=MODELS, label="Select Model", value=MODELS[3]),
714
- gr.Slider(minimum=0.1, maximum=1.0, value=0.2, step=0.1, label="Temperature"),
715
- gr.Slider(minimum=1, maximum=5, value=1, step=1, label="Number of API Calls"),
716
- gr.Checkbox(label="Use Web Search", value=True),
717
- gr.CheckboxGroup(label="Select documents to query"),
718
- gr.Audio(sources="microphone", type="filepath", label="Or speak your question (optional)")
719
  ],
720
- title="AI-powered PDF Chat and Web Search Assistant",
721
- description="Chat with your PDFs, use web search, or speak your questions.",
722
- theme=gr.themes.Soft(
723
- # ... (keep the existing theme configuration)
724
- ),
725
- css=css,
726
- examples=[
727
- # ... (keep the existing examples)
728
- ],
729
- cache_examples=False,
730
- analytics_enabled=False,
731
- textbox=gr.Textbox(placeholder="Type or speak your question", container=False, scale=7),
732
- chatbot = gr.Chatbot(
733
- show_copy_button=True,
734
- likeable=True,
735
- layout="bubble",
736
- height=400,
737
- value=initial_conversation()
738
- )
739
  )
740
 
741
- # Add file upload functionality
742
- with demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  gr.Markdown("## Upload and Manage PDF Documents")
744
  with gr.Row():
745
  file_input = gr.Files(label="Upload your PDF documents", file_types=[".pdf"])
@@ -754,35 +748,35 @@ with demo:
754
  update_button.click(
755
  update_vectors,
756
  inputs=[file_input, parser_dropdown],
757
- outputs=[update_output, demo.additional_inputs[-1]] # Use the CheckboxGroup from additional_inputs
758
  )
759
 
760
  # Add the refresh button functionality
761
  refresh_button.click(
762
  refresh_documents,
763
  inputs=[],
764
- outputs=[demo.additional_inputs[-1]] # Use the CheckboxGroup from additional_inputs
765
  )
766
 
767
  # Add the delete button functionality
768
  delete_button.click(
769
  delete_documents,
770
- inputs=[demo.additional_inputs[-1]], # Use the CheckboxGroup from additional_inputs
771
- outputs=[update_output, demo.additional_inputs[-1]]
772
  )
773
 
774
  gr.Markdown(
775
  """
776
  ## How to use
777
- 1. Upload PDF documents using the file input at the top.
778
- 2. Select the PDF parser (pypdf or llamaparse) and click "Upload Document" to update the vector store.
779
- 3. Select the documents you want to query using the checkboxes.
780
- 4. Ask questions in the chat interface.
781
- 5. Toggle "Use Web Search" to switch between PDF chat and web search.
782
- 6. Adjust Temperature and Number of API Calls to fine-tune the response generation.
783
- 7. Use the provided examples or ask your own questions.
 
784
  """
785
  )
786
-
787
  if __name__ == "__main__":
788
  demo.launch(share=True)
 
28
  ACCOUNT_ID = os.environ.get("CLOUDFARE_ACCOUNT_ID")
29
  API_TOKEN = os.environ.get("CLOUDFLARE_AUTH_TOKEN")
30
  API_BASE_URL = "https://api.cloudflare.com/client/v4/accounts/a17f03e0f049ccae0c15cdcf3b9737ce/ai/run/"
31
+ whisper_api = InferenceApi("openai/whisper-large-v2", token=huggingface_token)
 
 
32
 
33
  print(f"ACCOUNT_ID: {ACCOUNT_ID}")
34
  print(f"CLOUDFLARE_AUTH_TOKEN: {API_TOKEN[:5]}..." if API_TOKEN else "Not set")
 
278
  print(f"Final clean response: {final_response[:100]}...")
279
  return final_response
280
 
281
+ def chatbot_interface(message, history, model, temperature, num_calls):
282
+ if not message.strip():
283
+ return "", history
284
+
285
+ history = history + [(message, "")]
286
+
287
  try:
288
+ for response in respond(message, history, model, temperature, num_calls):
289
+ history[-1] = (message, response)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  yield history
291
+ except gr.CancelledError:
292
+ yield history
293
  except Exception as e:
294
+ logging.error(f"Unexpected error in chatbot_interface: {str(e)}")
295
+ history[-1] = (message, f"An unexpected error occurred: {str(e)}")
 
296
  yield history
297
 
298
  def retry_last_response(history, model, temperature, num_calls):
 
403
  logging.info(f"Model Used: {model}")
404
  logging.info(f"Selected Documents: {selected_docs}")
405
  logging.info(f"Use Web Search: {use_web_search}")
406
+
407
  if use_web_search:
408
  original_query = message
409
  rephrased_query = rephrase_query(message, conversation_manager)
410
  logging.info(f"Original query: {original_query}")
411
  logging.info(f"Rephrased query: {rephrased_query}")
412
+
413
  final_summary = ""
414
  for _ in range(num_calls):
415
  search_results = get_web_search_results(rephrased_query)
 
419
  final_summary += search_results[0]["error"] + "\n\n"
420
  else:
421
  summary = summarize_web_results(rephrased_query, search_results, conversation_manager)
422
+ final_summary += summary + "\n\n"
423
+
424
  if final_summary:
425
  conversation_manager.add_interaction(original_query, final_summary)
426
  yield final_summary
 
451
  if model.startswith("duckduckgo/"):
452
  # Use DuckDuckGo chat with context
453
  for partial_response in get_response_from_duckduckgo(message, model, context_str, num_calls, temperature):
454
+ yield partial_response
455
  elif model == "@cf/meta/llama-3.1-8b-instruct":
456
  # Use Cloudflare API
457
  for partial_response in get_response_from_cloudflare(prompt="", context=context_str, query=message, num_calls=num_calls, temperature=temperature, search_type="pdf"):
458
+ yield partial_response
459
  else:
460
  # Use Hugging Face API
461
  for partial_response in get_response_from_pdf(message, model, selected_docs, num_calls=num_calls, temperature=temperature):
462
+ yield partial_response
463
  except Exception as e:
464
  logging.error(f"Error with {model}: {str(e)}")
465
  if "microsoft/Phi-3-mini-4k-instruct" in model:
466
  logging.info("Falling back to Mistral model due to Phi-3 error")
467
  fallback_model = "mistralai/Mistral-7B-Instruct-v0.3"
468
+ yield from respond(message, history, fallback_model, temperature, num_calls, selected_docs)
469
  else:
470
  yield f"An error occurred with the {model} model: {str(e)}. Please try again or select a different model."
471
 
 
607
 
608
  logging.info("Finished generating response")
609
 
610
+ def transcribe(audio_file):
611
  if audio_file is None:
612
  return ""
613
 
614
+ with open(audio_file, "rb") as f:
615
+ audio_data = f.read()
 
 
 
 
 
 
616
 
617
+ response = whisper_api(audio_data)
618
+ return response["text"]
 
 
 
 
 
 
 
619
 
620
  def vote(data: gr.LikeData):
621
  if data.liked:
 
666
 
667
  custom_placeholder = "Ask a question (Note: You can toggle between Web Search and PDF Chat in Additional Inputs below)"
668
 
669
+ asr_interface = gr.Interface(
670
+ fn=transcribe,
671
+ inputs=[
672
+ gr.Audio(sources="microphone", type="filepath", optional=True)
 
 
 
 
 
 
 
 
673
  ],
674
+ outputs="text",
675
+ title="Speech to Text",
676
+ description="Speak your query, and it will be transcribed."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
  )
678
 
679
+ # Update the Gradio interface
680
+ with gr.Blocks() as demo:
681
+ gr.Markdown("# AI-powered PDF Chat and Web Search Assistant with Speech Input")
682
+
683
+ with gr.Row():
684
+ with gr.Column(scale=1):
685
+ asr_interface.render()
686
+
687
+ with gr.Column(scale=2):
688
+ chatbot = gr.ChatInterface(
689
+ respond,
690
+ additional_inputs=[
691
+ gr.Dropdown(choices=MODELS, label="Select Model", value=MODELS[3]),
692
+ gr.Slider(minimum=0.1, maximum=1.0, value=0.2, step=0.1, label="Temperature"),
693
+ gr.Slider(minimum=1, maximum=5, value=1, step=1, label="Number of API Calls"),
694
+ gr.Checkbox(label="Use Web Search", value=True),
695
+ gr.CheckboxGroup(label="Select documents to query")
696
+ ],
697
+ title="Chat with PDFs or Web Search",
698
+ description="Chat with your PDFs or use web search to answer questions.",
699
+ theme=gr.themes.Soft(
700
+ primary_hue="orange",
701
+ secondary_hue="amber",
702
+ neutral_hue="gray",
703
+ font=[gr.themes.GoogleFont("Exo"), "ui-sans-serif", "system-ui", "sans-serif"]
704
+ ).set(
705
+ body_background_fill_dark="#0c0505",
706
+ block_background_fill_dark="#0c0505",
707
+ block_border_width="1px",
708
+ block_title_background_fill_dark="#1b0f0f",
709
+ input_background_fill_dark="#140b0b",
710
+ button_secondary_background_fill_dark="#140b0b",
711
+ border_color_accent_dark="#1b0f0f",
712
+ border_color_primary_dark="#1b0f0f",
713
+ background_fill_secondary_dark="#0c0505",
714
+ color_accent_soft_dark="transparent",
715
+ code_background_fill_dark="#140b0b"
716
+ ),
717
+ css=css,
718
+ examples=[
719
+ ["Tell me about the contents of the uploaded PDFs."],
720
+ ["What are the main topics discussed in the documents?"],
721
+ ["Can you summarize the key points from the PDFs?"],
722
+ ["What's the latest news about artificial intelligence?"]
723
+ ],
724
+ cache_examples=False,
725
+ analytics_enabled=False,
726
+ textbox=gr.Textbox(placeholder="Ask a question about the uploaded PDFs or any topic", container=False, scale=7),
727
+ chatbot=gr.Chatbot(
728
+ show_copy_button=True,
729
+ likeable=True,
730
+ layout="bubble",
731
+ height=400,
732
+ value=initial_conversation()
733
+ )
734
+ )
735
+
736
+ # Add file upload functionality
737
  gr.Markdown("## Upload and Manage PDF Documents")
738
  with gr.Row():
739
  file_input = gr.Files(label="Upload your PDF documents", file_types=[".pdf"])
 
748
  update_button.click(
749
  update_vectors,
750
  inputs=[file_input, parser_dropdown],
751
+ outputs=[update_output, chatbot.additional_inputs[-1]]
752
  )
753
 
754
  # Add the refresh button functionality
755
  refresh_button.click(
756
  refresh_documents,
757
  inputs=[],
758
+ outputs=[chatbot.additional_inputs[-1]]
759
  )
760
 
761
  # Add the delete button functionality
762
  delete_button.click(
763
  delete_documents,
764
+ inputs=[chatbot.additional_inputs[-1]],
765
+ outputs=[update_output, chatbot.additional_inputs[-1]]
766
  )
767
 
768
  gr.Markdown(
769
  """
770
  ## How to use
771
+ 1. Use the microphone to speak your query, or type it in the chat interface.
772
+ 2. Upload PDF documents using the file input at the bottom.
773
+ 3. Select the PDF parser (pypdf or llamaparse) and click "Upload Document" to update the vector store.
774
+ 4. Select the documents you want to query using the checkboxes.
775
+ 5. Ask questions in the chat interface.
776
+ 6. Toggle "Use Web Search" to switch between PDF chat and web search.
777
+ 7. Adjust Temperature and Number of API Calls to fine-tune the response generation.
778
+ 8. Use the provided examples or ask your own questions.
779
  """
780
  )
 
781
  if __name__ == "__main__":
782
  demo.launch(share=True)