Cyfer-ap/AI-Coding-Tutor
1
1import gradio as gr2from backend.prompts import call_llm, summarize_history3 4import tempfile5import json6from datetime import datetime7 8def export_history(chat_history, format_choice):9 try:10 # Generate timestamp11 timestamp = datetime.now().strftime("%Y%m%d-%H%M")12 filename_base = f"chat-export-{timestamp}"13 14 if format_choice == "TXT":15 content = ""16 for user_msg, ai_msg in chat_history:17 content += f"{user_msg}\n{ai_msg}\n\n"18 suffix = ".txt"19 20 elif format_choice == "Markdown":21 content = ""22 for user_msg, ai_msg in chat_history:23 content += f"**User:** {user_msg}\n\n**AI:** {ai_msg}\n\n---\n"24 suffix = ".md"25 26 elif format_choice == "JSON":27 json_data = []28 for u, a in chat_history:29 json_data.append({"role": "user", "content": u})30 json_data.append({"role": "assistant", "content": a})31 content = json.dumps(json_data, indent=2)32 suffix = ".json"33 34 else:35 return "[Export Error] Unknown format."36 37 full_path = f"{tempfile.gettempdir()}/{filename_base}{suffix}"38 39 with open(full_path, "w", encoding="utf-8") as f:40 f.write(content)41 42 return full_path43 44 except Exception as e:45 return f"[Export Error] {str(e)}"46 47 48 49 50# Friendly name to model ID mapping51MODEL_MAP = {52 "Mistral": "mistralai/mistral-7b-instruct:free",53 "Code LLaMA": "meta-llama/llama-3.3-8b-instruct:free",54 "Qwen": "qwen/qwen3-235b-a22b:free",55 "Deepseek": "deepseek/deepseek-chat-v3-0324:free",56 "Google": "google/gemma-3-27b-it:free",57 "Anthropic": "anthropic/claude-sonnet-4"58}59 60summary_memory = ""61turn_counter = 062MAX_TURNS_BEFORE_SUMMARY = 663 64def process_message(message, chat_history, task_type, language, selected_model):65 global summary_memory, turn_counter66 turn_counter += 167 68 if turn_counter % MAX_TURNS_BEFORE_SUMMARY == 0:69 new_summary = summarize_history(chat_history, max_turns=MAX_TURNS_BEFORE_SUMMARY)70 summary_memory += "\n" + new_summary71 72 if task_type == "Explain":73 prompt = f"Explain the following programming problem:\n{message}"74 elif task_type == "Generate Code":75 prompt = f"Write complete {language} code to solve this:\n{message}\nWrap the code in triple backticks."76 elif task_type == "Generate Tests":77 prompt = f"Generate 5 test cases for this {language} problem/code:\n{message}"78 elif task_type == "Debug":79 prompt = f"Debug this {language} code:\n{message}\nShow corrected code and explain the fix."80 elif task_type == "Optimize":81 prompt = f"Optimize this {language} code:\n{message}\nSuggest improvements and rewrite it."82 83 context = "".join([f"User: {u}\nAssistant: {a}\n" for u, a in chat_history[-2:]])84 full_prompt = f"{summary_memory.strip()}\n\n{context}\nUser: {prompt}\nAssistant:"85 86 model_id = MODEL_MAP.get(selected_model, MODEL_MAP["Mistral"])87 response = call_llm(full_prompt, model=model_id)88 89 chat_history.append((f"๐ค {message}", f"๐ค {response}"))90 91 return "", chat_history92 93def reset_chat():94 global summary_memory, turn_counter95 summary_memory = ""96 turn_counter = 097 return "", []98 99def auto_select_model(task):100 if task == "Explain":101 return "Anthropic"102 elif task == "Generate Tests":103 return "Qwen"104 elif task == "Generate Code":105 return "Code LLaMA"106 elif task == "Debug":107 return "Deepseek"108 elif task == "Optimize":109 return "Mistral"110 return "Mistral"111 112with gr.Blocks() as demo:113 114 gr.HTML("""115 <style>116 /* Style for user (left-aligned) */117 .chatbot .message.user {118 background-color: #e0f7fa !important;119 color: black !important;120 text-align: left;121 border-radius: 10px;122 padding: 8px;123 }124 125 /* Style for assistant (right-aligned) */126 .chatbot .message.bot {127 background-color: #e8f5e9 !important;128 color: black !important;129 text-align: left;130 border-radius: 10px;131 padding: 8px;132 }133 134 </style>135 """)136 137 138 with gr.Row():139 gr.Markdown(140 """141 <h1 style="text-align: center;">AI Coding Tutor</h1>142 <p style="text-align: center;">Your personal AI tutor for competitive programming!</p>143 """144 )145 146 with gr.Row():147 task_type = gr.Dropdown(["Explain", "Generate Code", "Generate Tests", "Debug", "Optimize"],148 label="Task", value="Explain")149 language = gr.Dropdown(["Python", "C++", "Java", "Pseudocode"],150 label="Language", value="Python")151 model_select = gr.Dropdown(152 label="Model",153 choices=list(MODEL_MAP.keys()),154 value="Mistral"155 )156 157 task_type.change(fn=auto_select_model, inputs=task_type, outputs=model_select)158 159 gr.HTML("<div class='chatbot'>")160 chatbot = gr.Chatbot(render_markdown=True)161 gr.HTML("</div>")162 163 history = gr.State([])164 165 chatbot.clear(fn=reset_chat, outputs=[msg := gr.Textbox(visible=False), history])166 167 with gr.Row(equal_height=True):168 msg = gr.Code(169 scale=9,170 language="python",171 label="Type your message or paste your code here",172 lines=8173 )174 175 send_btn = gr.Button("Send", scale=1)176 177 send_btn.click(178 fn=process_message,179 inputs=[msg, history, task_type, language, model_select],180 outputs=[msg, chatbot],181 show_progress=True182 )183 184 example_prompts = [185 "Write a Python function to check if a number is prime.",186 "Explain the two-pointer technique with an example.",187 "Debug this code: def fact(n): return n * fact(n-1)",188 "Optimize a bubble sort implementation in Java.",189 "Generate test cases for a binary search algorithm."190 ]191 192 gr.Markdown("### ๐ก Click to Send Example Prompts")193 with gr.Row():194 for prompt in example_prompts:195 def make_prompt_click_handler(p):196 def handler(hist, task, lang, model):197 model_id = MODEL_MAP.get(model, MODEL_MAP["Mistral"])198 return process_message(p, hist, task, lang, model_id)199 200 return handler201 202 203 gr.Button(prompt).click(204 fn=make_prompt_click_handler(prompt),205 inputs=[history, task_type, language, model_select],206 outputs=[msg, chatbot],207 show_progress=True208 )209 gr.Markdown("### ๐ค Export Your Chat")210 export_format = gr.Dropdown(211 choices=["TXT", "Markdown", "JSON"],212 value="TXT",213 label="Select Export Format"214 )215 216 gr.Button("๐พ Download Chat").click(217 fn=export_history,218 inputs=[history, export_format],219 outputs=[gr.File()]220 )221 222 gr.Markdown("""223 **๐ Model Guide** 224 - ๐ง **Anthropic** โ Best for logic explanation & tutoring (Claude Sonnet) 225 - ๐งฉ **Qwen** โ Powerful long-form reasoning and test case generation 226 - ๐งโ๐ป **Code LLaMA** โ Best for clean code generation (LLaMA 3.3 8B) 227 - ๐ **Deepseek** โ Great for debugging and step-wise code evaluation 228 - ๐ฌ **Mistral** โ Balanced speed + code generation 229 - ๐ช **Google (Gemma)** โ Experimental for chat + compact explanations230 """)231 232 gr.Markdown("""233 ### โ ๏ธ Experimental AI Coding Tutor 234 This program is in an **experimental state**. Responses may vary depending on the model selected. Some models are **slower or temporarily unavailable** due to public server limits.235 236 - โก **Fastest models**: `Mistral`, `Code LLaMA` 237 - ๐ง **Best for logic**: `Anthropic`, `Qwen` 238 - ๐จโ๐ป **Best for code**: `Code LLaMA`, `Mistral` 239 - ๐ **Debugging support**: `Deepseek`240 """)241 242 demo.launch(pwa=True)243 