import gradio as gr import sys import json from io import StringIO from urllib import parse from tutor import Tutor def submit_chat(tutor_ctx, message): try: tutor = Tutor(context=tutor_ctx) for history in tutor.chat(message): yield [tutor.serialize(), history, None] except Exception as error: raise gr.Error(str(error)) def submit_code(tutor_ctx, editor, output): try: tutor = Tutor(context=tutor_ctx) for history in tutor.code(editor, output): yield [tutor.serialize(), history, None] except Exception as error: raise gr.Error(str(error)) def init_tutor(instructions, starter_code, age, name): tutor = Tutor(instructions, starter_code, age, name) return [tutor.serialize(), tutor._memory_as_history()] def run_code(code): buffer = StringIO() sys.stdout = buffer try: exec(code) return buffer.getvalue() except Exception as e: print(e) return buffer.getvalue() finally: sys.stdout = sys.__stdout__ def _query_param(request: gr.Request, param: str, default: str = None) -> str: try: return parse.parse_qs(parse.urlparse(request.headers["referer"]).query)[ param ][0] except: return default def load_level(request: gr.Request): level = _query_param(request, "level", "1") age = _query_param(request, "age", "12") name = _query_param(request, "name", "") with open(f"levels/{level}/metadata.json", "r") as f: data = json.load(f) instructions = open(f"levels/{level}/{data['instructions']}", "r").read() starter_code = open(f"levels/{level}/{data['starter_code']}", "r").read() return [instructions, starter_code, age, name] with gr.Blocks(title="CS Tutor") as demo: tutor_ctx = gr.State() age = gr.State() name = gr.State() with gr.Row(): instruction_panel = gr.Markdown() with gr.Row(): with gr.Column(scale=1): chatbot = gr.Chatbot(label="AI Tutor", value=[]) msg = gr.Textbox(show_label=False, placeholder="Type your message here...") msg.submit(submit_chat, [tutor_ctx, msg], [tutor_ctx, chatbot, msg]) with gr.Column(scale=2): editor = gr.Code( value="Loading...", language="python", interactive=True, show_label=True, label="Code Editor", lines=15, ) output = gr.Code( value="""Click "Run" to run your code.""", language="python", interactive=False, show_label=True, label="Output", ) with gr.Row(): run = gr.Button("Run") run.click( run_code, editor, output, queue=False, scroll_to_output=True ).then(submit_code, [tutor_ctx, editor, output], [tutor_ctx, chatbot]) demo.load(load_level, None, [instruction_panel, editor, age, name], queue=False).then( init_tutor, [instruction_panel, editor, age, name], [tutor_ctx, chatbot] ) demo.queue() demo.launch()