import os import google.generativeai as genai import gradio as gr from PIL import Image import io import speech_recognition as sr from deep_translator import GoogleTranslator import re # --- 1. Configure API Key --- try: GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY') if not GOOGLE_API_KEY: raise ValueError("API key not found. Please set GOOGLE_API_KEY in Hugging Face Space settings.") genai.configure(api_key=GOOGLE_API_KEY) except Exception as e: print(f"Error configuring API key: {e}") # --- 2. Initialize Translator --- translator = GoogleTranslator(source='auto', target='en') # --- 3. Define the System Prompt --- SYSTEM_PROMPT = """ You are "DiaBuddy," an AI assistant designed as a supportive informational and educational tool for individuals with Type 1 Diabetes (T1D), their families, and to assist diabetes educators by providing general information and explaining concepts. You support multiple languages, including English, Hindi, and Punjabi, translating responses to the user's preferred language. Your goal is to help users understand T1D better by answering their questions clearly, concisely, and safely. You aim to cover a broad range of T1D topics, from basic understanding to management principles. **ABSOLUTELY CRITICAL: You are an AI and CANNOT provide medical advice, diagnosis, or treatment recommendations. You must never replace the judgment or guidance of a qualified healthcare professional.** All users must be directed to consult their doctor or diabetes care team for any personal health concerns, treatment decisions, or insulin dosing. **IMPORTANT RULES & DISCLAIMERS:** 1. **MEDICAL ADVICE & INSULIN DOSING:** * You MUST NEVER suggest specific insulin dosages or tell a user how much insulin to take as direct medical advice. Your role is informational and educational ONLY. * You MAY provide an *illustrative mealtime calculation demonstration* ONLY IF the user provides ALL necessary *personal and clinically determined* parameters for that specific scenario. This demonstration MUST be heavily disclaimed as non-medical, illustrative, and subordinate to doctor's advice. * Outside of this constrained mealtime demonstration, if asked to calculate an insulin dose without all parameters, or if asked for a direct recommendation: Explain the general formulas involved, what personal parameters are needed, and then FIRMLY state that you CANNOT provide a specific dose or medical advice. * ALWAYS advise users to consult their doctor or a qualified healthcare provider for ALL treatment decisions, including insulin dosing, or to use the dosing parameters and methods prescribed by their healthcare team. 2. **Illustrative MEALTIME Insulin Calculation DEMONSTRATION (If User Provides ALL *Known* Parameters):** * You can demonstrate how insulin doses for a meal are calculated IF AND ONLY IF the user provides ALL of the following *personal, typically doctor-determined* parameters for their specific situation in their query. You must actively look for and extract these numerical values: 1. **Grams of carbohydrates eaten (Carbs)**. 2. Their **Insulin-to-Carb Ratio (ICR_value)** (e.g., if "my ICR is 10" or "1 unit for 10g", then ICR_value = 10). 3. Their **Current Blood Glucose (Current_BG)**. 4. Their **Target Blood Glucose (Target_BG)**. 5. Their **Insulin Sensitivity Factor (ISF_value)** or Correction Factor (CF_value) (e.g., if "my ISF is 50" or "1 unit drops 50", then ISF_value = 50). * If any of these parameters are missing from the user's query, you MUST state that you need all of them to demonstrate the mealtime calculation and that you cannot provide an actual dose or medical advice. Politely ask for the missing values if they wish to see the demonstration. * **If all parameters are present and you have successfully extracted their numerical values:** * **Perform the following calculations using the extracted values:** * Carb_Coverage_Dose = (Extracted Carbs) / (Extracted ICR_value) * If (Extracted Current_BG > Extracted Target_BG): Correction_Dose = (Extracted Current_BG - Extracted Target_BG) / (Extracted ISF_value) * Else (if Extracted Current_BG <= Extracted Target_BG): Correction_Dose = 0 * Total_Illustrative_Dose = Carb_Coverage_Dose + Correction_Dose * Round the Carb_Coverage_Dose, Correction_Dose, and Total_Illustrative_Dose to one or two decimal places as appropriate for insulin (e.g., 0.0, 0.5, 1.2 units). State if rounding was applied. * **CRUCIAL RESPONSE FORMAT FOR MEALTIME ILLUSTRATION (Fill in with extracted and calculated values):** "Okay, based on the numbers you've provided for this *illustrative mealtime example*: * Carbs eaten: [Extracted Carbs]g * Your stated ICR: 1 unit per [Extracted ICR_value]g carbs * Your stated Current BG: [Extracted Current_BG] mg/dL (or mmol/L, be consistent with user input if specified, otherwise assume mg/dL) * Your stated Target BG: [Extracted Target_BG] mg/dL * Your stated ISF: 1 unit drops BG by [Extracted ISF_value] mg/dL Here's how the calculation would look *for demonstration purposes only*, using the values you provided: 1. **Carb Coverage Dose:** [Extracted Carbs]g / [Extracted ICR_value] = [Calculated and Rounded Carb_Coverage_Dose] units. 2. **Correction Dose:** ([Extracted Current_BG] - [Extracted Target_BG]) / [Extracted ISF_value] = [Calculated and Rounded Correction_Dose] units. (This is 0 if your current BG is at or below your target BG). 3. **Total Illustrative Dose:** [Calculated and Rounded Carb_Coverage_Dose] units + [Calculated and Rounded Correction_Dose] units = [Calculated and Rounded Total_Illustrative_Dose] units. **VERY IMPORTANT DISCLAIMER (Mealtime Illustration):** * This is an **ILLUSTRATIVE CALCULATION ONLY**, based *solely* on the numbers you provided for this hypothetical scenario. * This is **NOT MEDICAL ADVICE** and **NOT A RECOMMENDATION for an actual insulin dose.** * Your personal ICR, ISF, and target BG are determined by your doctor and can change. Factors like active insulin (IOB), exercise, illness, and stress also significantly impact insulin needs and are NOT accounted for in this simplified demonstration. * **ALWAYS consult your doctor, diabetes educator, or use the specific dosing instructions and tools (like a pump calculator with IOB) prescribed by your healthcare team for any and all insulin dosing decisions. Incorrect insulin dosing is extremely dangerous.** Do you have any other general questions about T1D?" 3. **EXPLAINING EDUCATIONAL STARTING POINT ESTIMATIONS FOR ICR & ISF (e.g., "Rule of 400/1700")** * If a user (e.g., patient, parent, or educator-in-training) asks how Insulin-to-Carb Ratio (ICR) or Insulin Sensitivity Factor (ISF) can be initially estimated using common rules like the "Rule of 400" (for ICR) or "Rule of 1700" (for ISF), or similar phrasing, AND they provide their/the patient's Total Daily Dose of insulin (TDD). * You can then explain these educational estimation rules. You must extract the TDD value provided by the user to perform the example calculation for the rule. **To explain Estimated ICR (e.g., using a 'Rule of 400'):** "Some diabetes education programs use a formula like the 'Rule of 400' as a *starting point* to estimate an Insulin-to-Carb Ratio (ICR). This number (400) can vary – other common values are 450 or 500, often depending on the type of insulin used (e.g., rapid-acting analogs vs. regular) and other individual factors. The general idea is: Estimated ICR = 400 / Total Daily Dose (TDD) of insulin. For example, if the Total Daily Dose (TDD) you provided is [Extracted User's TDD] units, then an *estimated* ICR would be: 400 / [Extracted User's TDD] units = [Calculate and Round 400 / Extracted User's TDD] grams of carbs covered by 1 unit of insulin. **IMPORTANT:** This is just an initial estimate. The actual ICR must be determined and fine-tuned with a healthcare professional based on blood glucose monitoring and individual response." **To explain Estimated ISF (e.g., using a 'Rule of 1700'):** "Similarly, for estimating an Insulin Sensitivity Factor (ISF) or Correction Factor, a formula like the 'Rule of 1700' is sometimes used as a *starting point*. (Other common numbers are 1500 or 1800, varying with insulin type and individual). The formula is: Estimated ISF = 1700 / Total Daily Dose (TDD) of insulin. So, if the Total Daily Dose (TDD) you provided is [Extracted User's TDD] units, then an *estimated* ISF would be: 1700 / [Extracted User's TDD] units = [Calculate and Round 1700 / Extracted User's TDD] mg/dL. This means 1 unit of insulin is estimated to lower blood glucose by this many points (mg/dL). If BG is measured in mmol/L, this value would need conversion by dividing by 18. **IMPORTANT:** Again, this is a starting estimate. The actual ISF needs to be confirmed and adjusted by a healthcare professional." * **CRITICAL DISCLAIMER FOR THESE ESTIMATION RULE EXPLANATIONS:** After explaining either rule, you MUST add: "**Please remember, these 'rules' provide very general starting estimates often used in educational settings. They are NOT precise for every individual, especially for children where growth and changing insulin needs are common. Any ICR or ISF value, whether estimated by such a rule or determined otherwise, MUST be established, validated, and regularly reviewed by a qualified healthcare professional (like an endocrinologist or diabetes educator). Never change insulin doses or ratios based solely on these estimations without medical supervision. These formulas do not account for many individual factors like insulin resistance, activity levels, or type of insulin in detail.**" * **DO NOT automatically use an ICR or ISF derived from these rules for the 'Illustrative MEALTIME Insulin Calculation DEMONSTRATION' unless the user explicitly asks you to use *these specific estimated numbers* for that subsequent demonstration. If they do, you must reiterate the "double estimation" (estimated ratios for an illustrative dose) and the heightened need for extreme caution and professional consultation. It is always preferable for the mealtime dose illustration to use ICR/ISF values the user states are their *known, clinically determined* ones.** * If the user does not provide a TDD when asking about these rules, explain that the TDD is needed to show how the rule is applied and then give the general disclaimer about these rules being estimates requiring professional validation. 4. **CALORIE AND CARB ESTIMATION FROM IMAGE:** If a user uploads an image of food and asks for calorie or insulin information, you can analyze the image, attempt to identify the food items, and provide an ESTIMATED calorie count and carbohydrate content. If the user provides ALL necessary parameters (Carbs, ICR, Current_BG, Target_BG, ISF), you can use the estimated carbs to perform an illustrative insulin dose calculation. ALWAYS state that these are ESTIMATES and can vary based on portion size, specific ingredients, and preparation methods. For insulin calculations, include the full disclaimer as in rule 2. 5. **GENERAL MEDICAL INFORMATION DISCLAIMER (for all other topics):** For all other T1D information, you MUST ALWAYS explicitly state that your information is for educational and informational purposes only and is NOT a substitute for professional medical advice, diagnosis, or treatment. Always advise users to consult their doctor or a qualified healthcare provider with any questions they may have regarding a medical condition or before making any decisions related to their treatment. 6. **Scope:** Focus ONLY on Type 1 Diabetes. If asked about Type 2 Diabetes, briefly differentiate if necessary, but steer the conversation back to T1D or state your specialization. If asked about unrelated medical conditions or general topics, politely state your specialization in T1D and that you cannot answer. 7. **Tone:** Be empathetic, patient, understanding, and encouraging. Avoid jargon where possible, or explain it simply. Translate responses to the user's preferred language (English, Hindi, or Punjabi). 8. **Information Source:** Base your answers on generally accepted knowledge about T1D. Do not speculate or provide unverified information. 9. **Safety:** Do not provide information that could lead to harm. If a question seems to ask for dangerous advice, politely decline and reiterate the importance of consulting a healthcare professional. 10. **Emergency:** If a user describes symptoms of a medical emergency (e.g., severe hypoglycemia, DKA), advise them to seek immediate medical attention or call emergency services. """ # --- 4. Initialize the Gemini Model --- try: model = genai.GenerativeModel( model_name='gemini-1.5-flash-latest', system_instruction=SYSTEM_PROMPT, safety_settings={ 'HARM_CATEGORY_HARASSMENT': 'BLOCK_MEDIUM_AND_ABOVE', 'HARM_CATEGORY_HATE_SPEECH': 'BLOCK_MEDIUM_AND_ABOVE', 'HARM_CATEGORY_SEXUALLY_EXPLICIT': 'BLOCK_MEDIUM_AND_ABOVE', 'HARM_CATEGORY_DANGEROUS_CONTENT': 'BLOCK_MEDIUM_AND_ABOVE', } ) except Exception as e: print(f"Error initializing model: {e}") model = None # --- 5. Helper Functions --- def translate_text(text, target_lang): try: if not text: return "" translator = GoogleTranslator(source='auto', target=target_lang) translation = translator.translate(text) return translation except Exception as e: print(f"Translation error: {e}") return text # Fallback to original text def speech_to_text(audio_file, lang_code): recognizer = sr.Recognizer() try: with sr.AudioFile(audio_file) as source: audio = recognizer.record(source) text = recognizer.recognize_google(audio, language=lang_code) return text except Exception as e: print(f"Speech recognition error: {e}") return f"Error processing audio: {str(e)}" def extract_parameters(message): """Extract numerical parameters for insulin calculation from user message.""" carbs = None icr = None current_bg = None target_bg = None isf = None # Regex patterns to extract numerical values carbs_match = re.search(r'(\d+\.?\d*)\s*(g|grams?)\s*(of)?\s*carbs?', message, re.IGNORECASE) icr_match = re.search(r'ICR\s*(is|=)\s*(\d+\.?\d*)', message, re.IGNORECASE) or \ re.search(r'1\s*unit\s*(per|for)\s*(\d+\.?\d*)\s*(g|grams?)', message, re.IGNORECASE) current_bg_match = re.search(r'current\s*(BG|blood\s*glucose|sugar)\s*(is|=)\s*(\d+\.?\d*)', message, re.IGNORECASE) target_bg_match = re.search(r'target\s*(BG|blood\s*glucose|sugar)\s*(is|=)\s*(\d+\.?\d*)', message, re.IGNORECASE) isf_match = re.search(r'ISF\s*(is|=)\s*(\d+\.?\d*)', message, re.IGNORECASE) or \ re.search(r'1\s*unit\s*drops?\s*(BG|blood\s*glucose|sugar)?\s*(by)?\s*(\d+\.?\d*)', message, re.IGNORECASE) if carbs_match: carbs = float(carbs_match.group(1)) if icr_match: icr = float(icr_match.group(2)) if current_bg_match: current_bg = float(current_bg_match.group(3)) if target_bg_match: target_bg = float(target_bg_match.group(3)) if isf_match: isf = float(isf_match.group(3 if isf_match.lastindex == 3 else 4)) return carbs, icr, current_bg, target_bg, isf def calculate_insulin(carbs, icr, current_bg, target_bg, isf): """Perform illustrative insulin calculation with provided parameters.""" carb_dose = carbs / icr if carbs and icr else 0 correction_dose = ((current_bg - target_bg) / isf) if current_bg and target_bg and isf and current_bg > target_bg else 0 total_dose = carb_dose + correction_dose # Round to one or two decimal places carb_dose = round(carb_dose, 2) correction_dose = round(correction_dose, 2) total_dose = round(total_dose, 2) return carb_dose, correction_dose, total_dose # --- 6. Define the Chat Function for Gradio --- def dia_buddy_chat(message_text, history, image_input, audio_input, language): if not model: return "Error: The AI model could not be initialized. Please check the API key and model name.", history if not GOOGLE_API_KEY: return "Error: GOOGLE_API_KEY not configured.", history # Handle speech input input_text = message_text if audio_input is not None: lang_code = {'English': 'en-US', 'Hindi': 'hi-IN', 'Punjabi': 'pa-IN'}.get(language, 'en-US') input_text = speech_to_text(audio_input, lang_code) if "Error processing audio" in input_text: return translate_text(input_text, language.lower()), history # Translate input to English if not already in English input_lang = language.lower() if language in ['Hindi', 'Punjabi'] else 'en' if input_lang != 'en': input_text = translate_text(input_text, 'en') gemini_history = [] for user_msg, ai_msg in history: user_msg_text = user_msg if user_msg is not None else "" gemini_history.append({"role": "user", "parts": [{"text": user_msg_text}]}) if ai_msg is not None: ai_msg_text = ai_msg if ai_msg is not None else "" gemini_history.append({"role": "model", "parts": [{"text": ai_msg_text}]}) contents = [] for item in gemini_history: contents.append(item) user_message_parts = [] current_message_text = input_text if input_text is not None else "" if current_message_text: user_message_parts.append({"text": current_message_text}) estimated_carbs = None if image_input is not None: try: img_byte_arr = io.BytesIO() image_input.save(img_byte_arr, format='PNG') img_bytes = img_byte_arr.getvalue() user_message_parts.append({ "inline_data": { "mime_type": "image/png", "data": img_bytes } }) if not current_message_text.strip(): user_message_parts.insert(0, {"text": "Analyze this image. Identify the food items, estimate the carbohydrate content, and provide a nutritional breakdown including calories. If asked for insulin calculation, use the estimated carbs and provided parameters."}) else: user_message_parts.insert(0, {"text": current_message_text + " Additionally, analyze the food image to estimate carbohydrate content for insulin calculation."}) except Exception as e: print(f"Error processing image: {e}") return translate_text(f"Sorry, there was an error processing the image: {str(e)}", input_lang), history if not user_message_parts: if not current_message_text.strip() and image_input is None: return translate_text("Please type a message, speak, or upload an image to chat.", input_lang), history contents.append({"role": "user", "parts": user_message_parts}) try: response = model.generate_content(contents) response_text = "" if not response.candidates: response_text = "I'm sorry, I can't respond to that request. It might violate safety guidelines or there was an issue generating a response." if response.prompt_feedback and response.prompt_feedback.block_reason: response_text += f" (Reason: {response.prompt_feedback.block_reason})" elif response.candidates: candidate = response.candidates[0] if candidate.content and candidate.content.parts: part_text_list = [] for part in candidate.content.parts: if hasattr(part, 'text'): part_text_list.append(part.text) response_text = "".join(part_text_list) elif candidate.finish_reason == 'SAFETY': response_text = "I'm sorry, I can't respond to that. My safety filters prevented a response." if candidate.safety_ratings: for rating in candidate.safety_ratings: if rating.blocked: response_text += f" (Blocked due to: {rating.category})" else: response_text = "Sorry, I received an unexpected response format from the AI. Please try rephrasing." # Extract carbs from response if image was provided if image_input: carbs_match = re.search(r'estimated.*(\d+\.?\d*)\s*(g|grams?)\s*(of)?\s*carbs?', response_text, re.IGNORECASE) if carbs_match: estimated_carbs = float(carbs_match.group(1)) # Check for insulin calculation request is_insulin_question = any(keyword in current_message_text.lower() for keyword in ["insulin", "calculate", "dose"]) or image_input if is_insulin_question: carbs, icr, current_bg, target_bg, isf = extract_parameters(current_message_text) if image_input and estimated_carbs and not carbs: carbs = estimated_carbs if all([carbs, icr, current_bg, target_bg, isf]): carb_dose, correction_dose, total_dose = calculate_insulin(carbs, icr, current_bg, target_bg, isf) insulin_response = ( f"Okay, based on the numbers you've provided for this *illustrative mealtime example*:\n" f"* Carbs eaten: {carbs}g {'(estimated from image)' if image_input and estimated_carbs else ''}\n" f"* Your stated ICR: 1 unit per {icr}g carbs\n" f"* Your stated Current BG: {current_bg} mg/dL\n" f"* Your stated Target BG: {target_bg} mg/dL\n" f"* Your stated ISF: 1 unit drops BG by {isf} mg/dL\n\n" f"Here's how the calculation would look *for demonstration purposes only*, using the values you provided:\n" f"1. **Carb Coverage Dose:** {carbs}g / {icr} = {carb_dose} units.\n" f"2. **Correction Dose:** ({current_bg} - {target_bg}) / {isf} = {correction_dose} units. " f"(This is 0 if your current BG is at or below your target BG).\n" f"3. **Total Illustrative Dose:** {carb_dose} units + {correction_dose} units = {total_dose} units.\n\n" f"**VERY IMPORTANT DISCLAIMER (Mealtime Illustration):**\n" f"* This is an **ILLUSTRATIVE CALCULATION ONLY**, based *solely* on the numbers you provided " f"{'and estimated carbs from the image' if image_input and estimated_carbs else ''} for this hypothetical scenario.\n" f"* This is **NOT MEDICAL ADVICE** and **NOT A RECOMMENDATION for an actual insulin dose.**\n" f"* Your personal ICR, ISF, and target BG are determined by your doctor and can change. " f"Factors like active insulin (IOB), exercise, illness, and stress also significantly impact insulin needs " f"and are NOT accounted for in this simplified demonstration.\n" f"* **ALWAYS consult your doctor, diabetes educator, or use the specific dosing instructions and tools " f"(like a pump calculator with IOB) prescribed by your healthcare team for any and all insulin dosing decisions. " f"Incorrect insulin dosing is extremely dangerous.**\n" f"Do you have any other general questions about T1D?" ) response_text += "\n\n" + insulin_response elif image_input and estimated_carbs: response_text += ( f"\n\nTo calculate an illustrative insulin dose for the estimated {estimated_carbs}g carbs from the image, " f"please provide your Insulin-to-Carb Ratio (ICR), Insulin Sensitivity Factor (ISF), current blood glucose, " f"and target blood glucose. For example, you might say: 'My ICR is 10, ISF is 50, current BG is 280 mg/dL, " f"target BG is 100 mg/dL.'\n\n" f"**I am an AI and CANNOT provide medical advice or actual insulin doses.** " f"Always consult your doctor for dosing decisions." ) else: response_text += ( f"\n\nTo calculate an illustrative insulin dose, please provide ALL of the following: " f"grams of carbs eaten, Insulin-to-Carb Ratio (ICR), Insulin Sensitivity Factor (ISF), current blood glucose, " f"and target blood glucose. For example: 'I ate 35g carbs, my ICR is 15, ISF is 50, current BG is 280 mg/dL, " f"target BG is 100 mg/dL.'\n\n" f"**I am an AI and CANNOT provide medical advice or actual insulin doses.** " f"Always consult your doctor for dosing decisions." ) # Fallback safety check for insulin advice is_giving_direct_dose_advice_outside_template = ( any(phrase in response_text.lower() for phrase in ["you should take", "your dose is ", "the required insulin is "]) and not ("ILLUSTRATIVE CALCULATION ONLY" in response_text.upper() and "NOT MEDICAL ADVICE" in response_text.upper()) ) if is_insulin_question and is_giving_direct_dose_advice_outside_template: print(f"WARNING: Potentially unsafe insulin advice detected from LLM and overridden by Python fallback. Original query: '{current_message_text}'. LLM response (before override): '{response_text}'") response_text = ( "I understand you're asking about insulin doses. Calculating the right amount of insulin " "involves personal factors like your Insulin-to-Carb Ratio (ICR), Insulin Sensitivity Factor (ISF), " "and target blood sugar, all prescribed by your doctor.\n\n" "**I am an AI and CANNOT provide you with a specific insulin dose or direct medical advice.** " "If you'd like to see an *illustrative example* of how the math works for a mealtime dose, please provide your grams of carbs, " "your personal ICR, current BG, target BG, and ISF. Remember, any calculation shown would be for " "demonstration purposes only and not a real medical recommendation.\n\n" "Similarly, if you'd like to understand educational starting point estimations like the 'Rule of 400/1700', please provide your Total Daily Dose (TDD).\n\n" "Please use the dosing instructions and parameters provided by your doctor or diabetes educator. " "Incorrect insulin dosing can be very dangerous. If you're unsure, please contact your healthcare provider." ) # Translate response to user's preferred language response_text = translate_text(response_text, input_lang) updated_history = history + [[current_message_text, response_text]] return response_text, updated_history except Exception as e: print(f"Error during API call to Gemini: {e}") error_str = str(e).lower() if "api key not valid" in error_str: return translate_text("Error: Invalid API Key. Please check your GOOGLE_API_KEY in Space settings.", input_lang), history if "quota" in error_str or "resource_exhausted" in error_str: return translate_text("Error: You may have exceeded your API quota or the service is experiencing high load. Please check your Google Cloud billing or API limits, or try again later.", input_lang), history if "deadline" in error_str or "503" in error_str or "unavailable" in error_str: return translate_text("The AI service is currently busy or unavailable. Please try again in a moment.", input_lang), history if "google.api_core.exceptions" in str(type(e)): return translate_text(f"A Google API error occurred: {str(e)}. Please check the logs and try again.", input_lang), history return translate_text(f"Sorry, an unexpected error occurred while communicating with the AI service: {str(e)}", input_lang), history # --- 7. Create and Launch the Gradio Interface --- with gr.Blocks(theme="gradio/soft") as iface: gr.Markdown( """ # DiaBuddy - T1D Support Assistant 🩺 Ask me about Type 1 Diabetes in English, Hindi, or Punjabi! You can type, speak, or upload a food image for a calorie and carb estimate, and calculate an illustrative insulin dose with your parameters. **IMPORTANT DISCLAIMERS:** * **MEDICAL ADVICE:** I am an AI assistant. The information I provide is for educational purposes ONLY and is **NOT** a substitute for professional medical advice, diagnosis, or treatment. ALWAYS consult your doctor or a qualified healthcare provider for any personal health concerns. * **INSULIN DOSING:** I **CANNOT** and **WILL NOT** suggest specific insulin doses as direct medical advice. If you provide all necessary parameters (carbs, ICR, current BG, target BG, ISF for mealtime dose; or TDD for educational rule explanations), I can show an *illustrative example* of the calculation, but this is **NOT a recommendation** and you must consult your doctor for actual dosing. * **CALORIE AND CARB ESTIMATES:** Calorie and carbohydrate information provided from images are **ESTIMATES ONLY** and can vary significantly. * **SPEECH INPUT:** Speech recognition supports English and Hindi; Punjabi support may be limited. Upload an audio file if needed. """ ) chatbot_component = gr.Chatbot( [], elem_id="chatbot", label="DiaBuddy Chat", bubble_full_width=False, height=600, show_copy_button=True, ) with gr.Row(): language_selector = gr.Dropdown( choices=["English", "Hindi", "Punjabi"], label="Select Language", value="English" ) image_box = gr.Image(type="pil", label="Upload Food Image (Optional)", sources=["upload", "clipboard"]) audio_box = gr.Audio(type="filepath", label="Speak Your Question (Optional)", sources=["upload"]) with gr.Row(): text_box = gr.Textbox( label="Type your message or question here:", placeholder="Ask about T1D, upload a food image for carb estimation, or provide ALL your numbers (e.g., carbs, ICR, current BG, target BG, ISF) for an illustrative insulin calculation...", container=False, scale=7, show_label=False, ) submit_btn = gr.Button("Send", variant="primary", scale=1) def handle_chat_submit(user_message, chat_history_tuples, uploaded_image, audio_input, language): response, updated_history = dia_buddy_chat(user_message, chat_history_tuples, uploaded_image, audio_input, language) return response, updated_history, "", None, None text_box.submit( fn=handle_chat_submit, inputs=[text_box, chatbot_component, image_box, audio_box, language_selector], outputs=[text_box, chatbot_component, text_box, image_box, audio_box] ) submit_btn.click( fn=handle_chat_submit, inputs=[text_box, chatbot_component, image_box, audio_box, language_selector], outputs=[text_box, chatbot_component, text_box, image_box, audio_box] ) gr.Examples( examples=[ ["What are the common symptoms of Type 1 Diabetes?", None, None, "English"], ["टाइप 1 डायबिटीज के सामान्य लक्षण क्या हैं?", None, None, "Hindi"], ["ਟਾਈਪ 1 ਸ਼ੂਗਰ ਦੇ ਆਮ ਲੱਛਣ ਕੀ ਹਨ?", None, None, "Punjabi"], ["Can you explain carb counting for T1D?", None, None, "English"], ["My BG is 280 mg/dL, I ate 35g carbs. My ICR is 15, ISF is 50, and target BG is 100 mg/dL. Show an illustrative calculation.", None, None, "English"], ["मेरा बीजी 280 mg/dL है, मैंने 35g कार्ब्स खाए। मेरा ICR 15 है, ISF 50 है, और टारगेट बीजी 100 mg/dL है। एक उदाहरण गणना दिखाएं।", None, None, "Hindi"], ["Upload a food image and estimate carbs for insulin calculation.", None, None, "English"], ["Tell me about insulin pumps.", None, None, "English"], ], inputs=[text_box, image_box, audio_box, language_selector], label="Example Questions (For image or audio, upload a file)" ) if __name__ == "__main__": print("DiaBuddy is ready. Launching Gradio interface...") iface.launch()