CoolFace
Apppublic

Cyfer-ap/AI-Coding-Tutor

sourceHugging Faceupdated 1y agoView on Hugging Face
1likes
app.py243 linesDownload Raw Back to root
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