Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
Hybrid AI Assistant - General Purpose + Healthcare Billing Expert
|
| 4 |
-
Enhanced with Emotional UI and Voice Input - HUGGING FACE SPACES VERSION
|
| 5 |
"""
|
| 6 |
|
| 7 |
import os
|
|
@@ -15,6 +15,9 @@ import requests
|
|
| 15 |
import gradio as gr
|
| 16 |
from datetime import datetime
|
| 17 |
import random
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
# Configure logging
|
| 20 |
logging.basicConfig(level=logging.INFO)
|
|
@@ -427,34 +430,41 @@ def chat_with_assistant(message, history):
|
|
| 427 |
logger.error(f"Chat error: {e}")
|
| 428 |
return "I apologize, but I encountered an error processing your message. Please try again!"
|
| 429 |
|
| 430 |
-
def quick_code_lookup(code):
|
| 431 |
-
"""Quick billing code lookup function"""
|
| 432 |
-
try:
|
| 433 |
-
if not code or not code.strip():
|
| 434 |
-
return "Please enter a billing code to look up."
|
| 435 |
-
|
| 436 |
-
info = assistant.billing_db.lookup(code.strip())
|
| 437 |
-
if info:
|
| 438 |
-
result = f"**{info.code} ({info.code_type})**\n\n"
|
| 439 |
-
result += f"**Description:** {info.description}\n\n"
|
| 440 |
-
if info.additional_info:
|
| 441 |
-
result += f"**Details:** {info.additional_info}\n\n"
|
| 442 |
-
if info.category:
|
| 443 |
-
result += f"**Category:** {info.category}"
|
| 444 |
-
return result
|
| 445 |
-
else:
|
| 446 |
-
return f"Code '{code.strip()}' not found in database. Try asking in the chat for more help!"
|
| 447 |
-
except Exception as e:
|
| 448 |
-
logger.error(f"Code lookup error: {e}")
|
| 449 |
-
return "Error looking up code. Please try again."
|
| 450 |
-
|
| 451 |
def process_voice_input(audio_file):
|
| 452 |
-
"""Process voice input
|
| 453 |
if audio_file is None:
|
| 454 |
-
return "No audio received. Please try recording again."
|
| 455 |
|
| 456 |
-
|
| 457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 458 |
|
| 459 |
def reset_conversation():
|
| 460 |
"""Reset the conversation context"""
|
|
@@ -662,37 +672,20 @@ def create_gradio_interface():
|
|
| 662 |
description="π¬ Start chatting! I can help with healthcare billing codes, general questions, and adapt to your emotional tone."
|
| 663 |
)
|
| 664 |
|
| 665 |
-
#
|
|
|
|
| 666 |
with gr.Row():
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
lines=6,
|
| 679 |
-
interactive=False
|
| 680 |
-
)
|
| 681 |
-
|
| 682 |
-
with gr.Column(scale=1):
|
| 683 |
-
gr.Markdown("### ποΈ Voice Input")
|
| 684 |
-
audio_input = gr.Audio(
|
| 685 |
-
sources=["microphone"],
|
| 686 |
-
type="filepath",
|
| 687 |
-
label="Voice Input"
|
| 688 |
-
)
|
| 689 |
-
voice_btn = gr.Button("π€ Process Voice", elem_classes=["custom-button"])
|
| 690 |
-
voice_output = gr.Textbox(
|
| 691 |
-
label="Voice Processing Result",
|
| 692 |
-
placeholder="Voice processing result will appear here...",
|
| 693 |
-
lines=3,
|
| 694 |
-
interactive=False
|
| 695 |
-
)
|
| 696 |
|
| 697 |
# Features Section
|
| 698 |
gr.HTML("""
|
|
@@ -714,8 +707,8 @@ def create_gradio_interface():
|
|
| 714 |
</div>
|
| 715 |
<div class="feature-card">
|
| 716 |
<div class="feature-icon">ποΈ</div>
|
| 717 |
-
<h3>Voice
|
| 718 |
-
<p>
|
| 719 |
</div>
|
| 720 |
</div>
|
| 721 |
""")
|
|
@@ -730,41 +723,20 @@ def create_gradio_interface():
|
|
| 730 |
interactive=False
|
| 731 |
)
|
| 732 |
|
| 733 |
-
# Usage Information
|
| 734 |
-
gr.Markdown("""
|
| 735 |
-
### π‘ How to Use:
|
| 736 |
-
- **Healthcare Codes**: Mention any billing code (A0429, 99213, etc.) and get detailed information
|
| 737 |
-
- **General Questions**: Ask anything - from recipes to complex topics, I'm here to help!
|
| 738 |
-
- **Emotional Support**: I adapt my tone based on your mood - express how you're feeling
|
| 739 |
-
- **Voice Input**: Use the voice recorder for hands-free interaction (framework ready)
|
| 740 |
-
- **Quick Lookup**: Use the code lookup tool for instant billing code information
|
| 741 |
-
|
| 742 |
-
### π₯ Supported Code Types:
|
| 743 |
-
- **CPT Codes**: Current Procedural Terminology (99213, 93000, etc.)
|
| 744 |
-
- **HCPCS Codes**: Healthcare Common Procedure Coding (A0429, J3420, etc.)
|
| 745 |
-
- **ICD-10 Codes**: International Classification of Diseases (Z79.899, etc.)
|
| 746 |
-
- **DRG Codes**: Diagnosis Related Groups (DRG470, etc.)
|
| 747 |
-
""")
|
| 748 |
-
|
| 749 |
# Event Handlers
|
| 750 |
-
lookup_btn.click(
|
| 751 |
-
quick_code_lookup,
|
| 752 |
-
inputs=[code_input],
|
| 753 |
-
outputs=[code_output]
|
| 754 |
-
)
|
| 755 |
-
|
| 756 |
voice_btn.click(
|
| 757 |
process_voice_input,
|
| 758 |
inputs=[audio_input],
|
| 759 |
-
outputs=[
|
| 760 |
)
|
| 761 |
|
| 762 |
reset_btn.click(
|
| 763 |
reset_conversation,
|
| 764 |
-
outputs=[status_output,
|
| 765 |
)
|
| 766 |
|
| 767 |
return demo
|
|
|
|
| 768 |
# ============= Launch Application =============
|
| 769 |
|
| 770 |
# Create and configure the interface
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
Hybrid AI Assistant - General Purpose + Healthcare Billing Expert
|
| 4 |
+
Enhanced with Emotional UI and Voice Input/Output - HUGGING FACE SPACES VERSION
|
| 5 |
"""
|
| 6 |
|
| 7 |
import os
|
|
|
|
| 15 |
import gradio as gr
|
| 16 |
from datetime import datetime
|
| 17 |
import random
|
| 18 |
+
import speech_recognition as sr
|
| 19 |
+
from gtts import gTTS
|
| 20 |
+
from io import BytesIO
|
| 21 |
|
| 22 |
# Configure logging
|
| 23 |
logging.basicConfig(level=logging.INFO)
|
|
|
|
| 430 |
logger.error(f"Chat error: {e}")
|
| 431 |
return "I apologize, but I encountered an error processing your message. Please try again!"
|
| 432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
def process_voice_input(audio_file):
|
| 434 |
+
"""Process voice input using speech recognition"""
|
| 435 |
if audio_file is None:
|
| 436 |
+
return "No audio received. Please try recording again.", None
|
| 437 |
|
| 438 |
+
try:
|
| 439 |
+
# Initialize recognizer
|
| 440 |
+
recognizer = sr.Recognizer()
|
| 441 |
+
|
| 442 |
+
# Load audio file
|
| 443 |
+
with sr.AudioFile(audio_file) as source:
|
| 444 |
+
audio = recognizer.record(source)
|
| 445 |
+
|
| 446 |
+
# Recognize speech using Google Speech Recognition
|
| 447 |
+
text = recognizer.recognize_google(audio)
|
| 448 |
+
logger.info(f"Recognized text: {text}")
|
| 449 |
+
|
| 450 |
+
# Process the recognized text through the assistant
|
| 451 |
+
response, sentiment = assistant.process_message(text.strip())
|
| 452 |
+
|
| 453 |
+
# Generate audio response
|
| 454 |
+
tts = gTTS(text=response, lang='en')
|
| 455 |
+
audio_buffer = BytesIO()
|
| 456 |
+
tts.write_to_fp(audio_buffer)
|
| 457 |
+
audio_buffer.seek(0)
|
| 458 |
+
|
| 459 |
+
return response, audio_buffer
|
| 460 |
+
except sr.UnknownValueError:
|
| 461 |
+
return "Sorry, I couldn't understand the audio. Please try speaking clearly or typing your question.", None
|
| 462 |
+
except sr.RequestError as e:
|
| 463 |
+
logger.error(f"Speech recognition error: {e}")
|
| 464 |
+
return "Error processing audio. Please try again or type your question.", None
|
| 465 |
+
except Exception as e:
|
| 466 |
+
logger.error(f"Voice processing error: {e}")
|
| 467 |
+
return "Error processing voice input. Please try again.", None
|
| 468 |
|
| 469 |
def reset_conversation():
|
| 470 |
"""Reset the conversation context"""
|
|
|
|
| 672 |
description="π¬ Start chatting! I can help with healthcare billing codes, general questions, and adapt to your emotional tone."
|
| 673 |
)
|
| 674 |
|
| 675 |
+
# Voice Input/Output Section
|
| 676 |
+
gr.Markdown("### ποΈ Voice Interaction")
|
| 677 |
with gr.Row():
|
| 678 |
+
audio_input = gr.Audio(
|
| 679 |
+
sources=["microphone"],
|
| 680 |
+
type="filepath",
|
| 681 |
+
label="Speak to the Assistant"
|
| 682 |
+
)
|
| 683 |
+
audio_output = gr.Audio(
|
| 684 |
+
label="Assistant's Response",
|
| 685 |
+
type="filepath",
|
| 686 |
+
interactive=False
|
| 687 |
+
)
|
| 688 |
+
voice_btn = gr.Button("π€ Process Voice", elem_classes=["custom-button"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
|
| 690 |
# Features Section
|
| 691 |
gr.HTML("""
|
|
|
|
| 707 |
</div>
|
| 708 |
<div class="feature-card">
|
| 709 |
<div class="feature-icon">ποΈ</div>
|
| 710 |
+
<h3>Voice Interaction</h3>
|
| 711 |
+
<p>Hands-free interaction with voice input and output.</p>
|
| 712 |
</div>
|
| 713 |
</div>
|
| 714 |
""")
|
|
|
|
| 723 |
interactive=False
|
| 724 |
)
|
| 725 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 726 |
# Event Handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
voice_btn.click(
|
| 728 |
process_voice_input,
|
| 729 |
inputs=[audio_input],
|
| 730 |
+
outputs=[chatbot, audio_output]
|
| 731 |
)
|
| 732 |
|
| 733 |
reset_btn.click(
|
| 734 |
reset_conversation,
|
| 735 |
+
outputs=[status_output, chatbot]
|
| 736 |
)
|
| 737 |
|
| 738 |
return demo
|
| 739 |
+
|
| 740 |
# ============= Launch Application =============
|
| 741 |
|
| 742 |
# Create and configure the interface
|