TGChandu/Language_Learning_ChatBot
0
1 2import os3import sqlite34import datetime5import pandas as pd6import gradio as gr7 8from langchain_openai import ChatOpenAI9from langchain_core.messages import SystemMessage, HumanMessage, AIMessage10 11# ✅ Load API key securely12openai_api_key = os.environ["OPENAI_API_KEY"]13 14# ✅ Setup SQLite database (local to HF Space)15db_path = 'mistakes.db'16conn = sqlite3.connect(db_path, check_same_thread=False)17cursor = conn.cursor()18 19cursor.execute("""20CREATE TABLE IF NOT EXISTS mistakes (21 id INTEGER PRIMARY KEY AUTOINCREMENT,22 user_input TEXT,23 mistake_type TEXT,24 correction TEXT,25 timestamp TEXT26)27""")28conn.commit()29 30# ✅ OpenAI model setup31llm = ChatOpenAI(32 model="gpt-3.5-turbo",33 temperature=0.7,34 openai_api_key=openai_api_key35)36 37# 🧠 Global state38session_state = {39 "known_language": "",40 "target_language": "",41 "proficiency_level": "",42 "scene": "",43 "messages": [],44 "scene_prompt": ""45}46 47scenes = [48 "Ordering food at a restaurant",49 "Shopping at a clothing store",50 "Asking for directions in a new city",51 "Introducing yourself to someone",52 "Booking a hotel room"53]54 55def setup_profile(known_language, target_language, level, selected_scene):56 if not all([known_language, target_language, level, selected_scene]):57 return "❌ Please fill all fields before starting.", gr.update(interactive=False), gr.update(interactive=False)58 59 session_state["known_language"] = known_language60 session_state["target_language"] = target_language61 session_state["proficiency_level"] = level62 session_state["scene"] = selected_scene63 64 prompt = f"""65You are a friendly, multilingual language tutor helping a user learn {target_language}.66 67They are a {level.lower()} learner whose native language is {known_language}.68Set the scene: {selected_scene}.69 70Start the conversation in {target_language} only.71Use simple vocabulary and grammar suited for a {level.lower()} learner.72Do NOT include translations. Just speak in {target_language}.73"""74 session_state["scene_prompt"] = prompt75 session_state["messages"] = [SystemMessage(content=prompt)]76 77 try:78 first_msg = llm.invoke(session_state["messages"])79 except Exception as e:80 return f"❌ Error: {str(e)}", gr.update(interactive=False), gr.update(interactive=False)81 82 session_state["messages"].append(first_msg)83 return f"Scene set: {selected_scene}\n\n🤖 Bot ({target_language}): {first_msg.content}", gr.update(interactive=True), gr.update(interactive=True)84 85def handle_message(user_input, chat_history):86 if user_input.strip().lower() in ["exit", "quit"]:87 return chat_history + [[user_input, "🛑 Session ended."]], gr.update(interactive=False)88 89 session_state["messages"].append(HumanMessage(content=user_input))90 91 correction_prompt = f"""92The user is learning {session_state['target_language']} and just said: "{user_input}"93 94Please do two things:951. Reply in {session_state['target_language']} ONLY, continuing the {session_state['scene']} scene.962. If there's a mistake, give a short explanation in English and provide the correction.97 98Use this format:99[Bot reply in {session_state['target_language']}]100[Mistake] (optional)101[Correction] (optional)102"""103 104 session_state["messages"].append(SystemMessage(content=correction_prompt))105 reply = llm.invoke(session_state["messages"])106 session_state["messages"].append(AIMessage(content=reply.content))107 108 reply_lines = reply.content.strip().split("\n")109 bot_reply = reply_lines[0]110 correction_info = "\n".join(reply_lines[1:]).strip()111 112 if correction_info:113 timestamp = datetime.datetime.now().isoformat()114 cursor.execute("""115 INSERT INTO mistakes (user_input, mistake_type, correction, timestamp)116 VALUES (?, ?, ?, ?)117 """, (user_input, "General", correction_info, timestamp))118 conn.commit()119 120 full_bot_reply = bot_reply121 if correction_info:122 full_bot_reply += f"\n\n🔧 {correction_info}"123 124 chat_history.append([user_input, full_bot_reply])125 return chat_history, gr.update()126 127def show_summary():128 try:129 thread_safe_conn = sqlite3.connect(db_path, check_same_thread=False)130 df = pd.read_sql_query("SELECT * FROM mistakes", thread_safe_conn)131 thread_safe_conn.close()132 133 if df.empty:134 return "✅ No mistakes found in this session. Great job!"135 136 summary = "📚 Summary of Mistakes:\n\n"137 for i, row in df.iterrows():138 summary += f"{i+1}. ❌ '{row['user_input']}'\n"139 summary += f" 🔧 Correction: {row['correction']}\n"140 summary += f" 🕒 {row['timestamp']}\n\n"141 142 summary += f"📌 Total Mistakes: {len(df)}\n"143 summary += "🧠 Tip: Focus on sentence structure, vocabulary, and grammar usage."144 return summary145 146 except Exception as e:147 return f"❌ Error while generating summary: {str(e)}"148 149# 🎛️ Gradio UI150with gr.Blocks() as demo:151 gr.Markdown("## 🌍 Multilingual Language Learning Chatbot")152 153 with gr.Accordion("Set Up Your Learning Profile", open=True):154 known_lang = gr.Textbox(label="What is your native/known language?", placeholder="e.g., English")155 target_lang = gr.Textbox(label="Which language do you want to learn?", placeholder="e.g., Spanish")156 level = gr.Dropdown(["Beginner", "Intermediate", "Advanced"], label="Your proficiency level")157 scene = gr.Radio(scenes, label="Choose a practice scene")158 start_btn = gr.Button("Start Conversation")159 profile_output = gr.Textbox(label="Bot's First Message")160 161 chatbot = gr.Chatbot()162 msg = gr.Textbox(label="Your message", placeholder="Type here and press Enter...")163 send_btn = gr.Button("Send")164 summary_btn = gr.Button("Show Mistake Summary")165 summary_output = gr.Textbox(label="Session Summary")166 167 msg.interactive = False168 send_btn.interactive = False169 170 def start_chat(known, target, lvl, scn):171 return setup_profile(known, target, lvl, scn)172 173 start_btn.click(fn=start_chat, inputs=[known_lang, target_lang, level, scene], outputs=[profile_output, msg, send_btn])174 send_btn.click(handle_message, inputs=[msg, chatbot], outputs=[chatbot, msg])175 msg.submit(handle_message, inputs=[msg, chatbot], outputs=[chatbot, msg])176 summary_btn.click(show_summary, outputs=[summary_output])177 178demo.launch()179 