import gradio as gr import os from dotenv import load_dotenv from ai_core import analyze_image_with_query from audio_utils import transcribe_with_groq, text_to_speech_with_gtts from image_utils import encode_image load_dotenv() # --- Configuration --- GROQ_API_KEY = os.environ.get("GROQ_API_KEY") STT_MODEL = "whisper-large-v3" VISION_MODEL = "meta-llama/llama-4-scout-17b-16e-instruct" SYSTEM_PROMPT = """You are SymptoScan MD, an AI medical assistant. Your role is to act as a professional, empathetic, and knowledgeable doctor. When analyzing the user's symptoms and any provided medical images, please follow these guidelines: 1. **Analyze Symptoms:** Carefully consider the user's described symptoms from the transcript. 2. **Analyze Image:** If an image is provided, analyze it in detail for any visible signs related to the symptoms. 3. **Provide a Possible Diagnosis:** Based on the text and image, provide a potential diagnosis or a few possible explanations for the symptoms. 4. **Suggest Next Steps:** Recommend clear and safe next steps for the user. This could include seeing a specialist, trying over-the-counter remedies, or making lifestyle changes. 5. **Maintain a Professional Tone:** Your response should be clear, concise, and easy for a non-medical person to understand. 6. **Include a Disclaimer:** ALWAYS end your response with the following disclaimer: 'Disclaimer: I am an AI assistant and not a real doctor. This is not a real medical diagnosis. Please consult a qualified healthcare professional for any medical concerns.' Your primary goal is to be helpful and safe. Do not provide any information that could be dangerous or misleading. """ # --- Main Processing Function --- def process_inputs(audio_filepath, image_filepath): transcript = "No audio was provided." if audio_filepath: try: transcript = transcribe_with_groq( stt_model=STT_MODEL, audio_filepath=audio_filepath, groq_api_key=GROQ_API_KEY ) except Exception as e: return f"Error in transcription: {e}", "", None if image_filepath: try: encoded_image = encode_image(image_filepath) query = f"{SYSTEM_PROMPT}\n\nUser symptoms: {transcript}" doctor_response = analyze_image_with_query( query=query, model=VISION_MODEL, encoded_image=encoded_image, groq_api_key=GROQ_API_KEY ) except Exception as e: return transcript, f"Error in AI analysis: {e}", None else: doctor_response = "No image provided. Please upload an image for analysis." try: voice_path = text_to_speech_with_gtts( input_text=doctor_response, output_filepath="symptoscan_md_response.mp3" ) except Exception as e: return transcript, doctor_response, f"Error in generating audio: {e}" return transcript, doctor_response, voice_path # --- Gradio UI --- professional_theme = gr.themes.Soft( primary_hue="teal", secondary_hue="blue", neutral_hue="slate", ).set( body_background_fill="#F0F4F8", ) with gr.Blocks(title="SymptoScan MD", theme=professional_theme, css=".gradio-container { max-width: 900px !important; margin: auto !important; }") as demo: gr.Markdown( """ # 🩺 SymptoScan MD ### Your AI-Powered Visual Health Assistant Upload a medical image (e.g., a skin condition) and describe your symptoms. Our AI will provide a preliminary analysis and suggest next steps. """ ) with gr.Row(equal_height=True): with gr.Column(scale=1): audio_input = gr.Audio(sources=["microphone"], type="filepath", label="🎤 Record Your Symptoms") image_input = gr.Image(type="filepath", label="🖼️ Upload Medical Image") submit_btn = gr.Button("Analyze Symptoms", variant="primary") with gr.Column(scale=2): transcript_output = gr.Textbox(label="📝 Your Symptoms (Transcribed)", lines=4, interactive=False) response_output = gr.Textbox(label="👩‍⚕️ AI Doctor's Analysis", lines=8, interactive=False) audio_output = gr.Audio(label="🔊 AI Voice Response", interactive=False) # --- Logic --- submit_btn.click( fn=process_inputs, inputs=[audio_input, image_input], outputs=[transcript_output, response_output, audio_output], api_name="analyze" ) if __name__ == "__main__": demo.launch(debug=True)