Spaces:
Build error
Build error
| # ── Cell: PELS Gradio App (Scenario-Based) ──────────────────────────────────── | |
| import gradio as gr | |
| import torch | |
| import re | |
| import random | |
| model.eval() | |
| torch.cuda.empty_cache() | |
| RUBRIC = """C1 Foundations (15%): Task clarity, role setup, AI awareness. | |
| C2 Design (20%): Prompt structure, patterns (few-shot, CoT, role+task+constraint). | |
| C3 Output Spec (20%): Format, length, tone, structure constraints. | |
| C4 Domain Application (20%): Domain vocabulary, contextual accuracy. | |
| C5 Ethics (15%): No harmful/biased framing. Score=1 triggers automatic Final Score override to 1.0. | |
| C6 Metacognition (10%): Self-awareness, iteration design, fallback handling.""" | |
| MAX_LENGTH = 512 | |
| MAX_NEW_TOKENS = 150 | |
| # ── Scenario bank ───────────────────────────────────────────────────────────── | |
| # Each scenario has: | |
| # "scenario" — the situation shown to the user | |
| # "task" — what they are asked to do (no hints on HOW to prompt) | |
| # The user must figure out how to write the prompt themselves. | |
| SCENARIOS = { | |
| "CAREER": [ | |
| { | |
| "scenario": "Rohan is a mechanical engineer with 5 years of experience who wants to switch into data science. He has done one online Python course but has no real projects yet. He has an interview at a data analytics firm next month.", | |
| "task": "Write an AI prompt that helps Rohan prepare for this career transition.", | |
| }, | |
| { | |
| "scenario": "Priya has been a school teacher for 8 years and wants to move into corporate L&D (Learning & Development). She has no corporate experience but has designed curriculum and trained 200+ students.", | |
| "task": "Write an AI prompt that helps Priya position herself for an L&D role.", | |
| }, | |
| { | |
| "scenario": "Amir graduated 6 months ago with a BCA degree and has been applying for software developer roles but getting no callbacks. His resume lists his college projects but no internships.", | |
| "task": "Write an AI prompt that helps Amir fix the problem and get more callbacks.", | |
| }, | |
| { | |
| "scenario": "Sneha is a marketing manager at a mid-size company. She wants to ask for a promotion to Director but has never negotiated salary or title before and doesn't know how to make the case.", | |
| "task": "Write an AI prompt that helps Sneha prepare for this conversation with her manager.", | |
| }, | |
| ], | |
| "EDUCATION": [ | |
| { | |
| "scenario": "A Grade 9 teacher needs to explain the concept of compound interest to students who understand basic multiplication and percentages but have never studied finance or banking.", | |
| "task": "Write an AI prompt that produces a teaching resource for this class.", | |
| }, | |
| { | |
| "scenario": "A university professor wants to check whether her 2nd-year engineering students have understood Newton's Laws of Motion — specifically common misconceptions students have about inertia.", | |
| "task": "Write an AI prompt that generates an assessment to test this understanding.", | |
| }, | |
| { | |
| "scenario": "A homeschooling parent needs to teach their 10-year-old child about climate change in a way that is factually accurate but not scary or overwhelming, using everyday examples.", | |
| "task": "Write an AI prompt that creates an age-appropriate lesson on this topic.", | |
| }, | |
| { | |
| "scenario": "A coding bootcamp instructor wants to introduce recursion to students who are comfortable with loops (for/while) but have never seen a function call itself.", | |
| "task": "Write an AI prompt that creates a beginner-friendly explanation with an exercise.", | |
| }, | |
| ], | |
| "TECHNOLOGY": [ | |
| { | |
| "scenario": "A junior developer at a startup wrote a Python script that reads a CSV file and calculates monthly sales totals — but it crashes whenever a cell is empty or contains text instead of a number.", | |
| "task": "Write an AI prompt that helps fix and improve this script.", | |
| }, | |
| { | |
| "scenario": "A non-technical product manager needs to explain to her team why their app is slow. The engineering team says it is a 'database N+1 query problem' but she doesn't understand what that means.", | |
| "task": "Write an AI prompt that produces an explanation she can actually understand and relay to stakeholders.", | |
| }, | |
| { | |
| "scenario": "A small business owner wants to build a simple website contact form that stores submissions in a Google Sheet — they have no coding experience and a budget of zero.", | |
| "task": "Write an AI prompt that gives them a practical, step-by-step solution.", | |
| }, | |
| { | |
| "scenario": "A data analyst has a pandas DataFrame with 500,000 rows. Her current code takes 4 minutes to run a groupby aggregation. Her manager wants results in under 30 seconds.", | |
| "task": "Write an AI prompt that helps her optimise the code.", | |
| }, | |
| ], | |
| "HEALTHCARE": [ | |
| { | |
| "scenario": "A 45-year-old patient was just diagnosed with pre-diabetes. Their doctor told them to 'watch their diet and exercise more' but gave no specific guidance. The patient is confused about what to actually do.", | |
| "task": "Write an AI prompt that produces practical, safe guidance for this patient.", | |
| }, | |
| { | |
| "scenario": "A nurse manager at a clinic needs to train new staff on the correct procedure for hand hygiene according to WHO guidelines — in a way that is quick to read and easy to remember during a busy shift.", | |
| "task": "Write an AI prompt that creates this training material.", | |
| }, | |
| { | |
| "scenario": "A medical student is struggling to remember the differences between Type 1 and Type 2 Diabetes — the symptoms, causes, treatment approaches, and which patient populations are typically affected.", | |
| "task": "Write an AI prompt that creates a study aid for this topic.", | |
| }, | |
| { | |
| "scenario": "A hospital wants to send a clear, non-alarming message to patients reminding them to get their annual flu vaccination — the message will go out via SMS so it must be very short.", | |
| "task": "Write an AI prompt that generates this patient communication.", | |
| }, | |
| ], | |
| "LEGAL": [ | |
| { | |
| "scenario": "A freelance graphic designer in Pune completed a logo project for a client who is now refusing to pay the ₹25,000 invoice, claiming the work was 'not what was agreed'. There was a WhatsApp conversation but no formal contract.", | |
| "task": "Write an AI prompt that helps the designer understand their options and next steps.", | |
| }, | |
| { | |
| "scenario": "A first-time landlord in Bangalore wants to rent out their apartment. They have heard that verbal agreements can cause problems and want to create a proper rental agreement that protects them legally.", | |
| "task": "Write an AI prompt that helps them draft or understand what should be in this agreement.", | |
| }, | |
| { | |
| "scenario": "An employee received a termination letter from their company citing 'performance issues' but believes they were fired because they filed a complaint against their manager last month.", | |
| "task": "Write an AI prompt that helps this person understand whether they have a case and what to do.", | |
| }, | |
| { | |
| "scenario": "A startup founder is about to sign a 3-year office lease. They have never signed a commercial lease before and are worried about clauses that could trap them if the startup fails in year one.", | |
| "task": "Write an AI prompt that helps them know what to watch out for in this agreement.", | |
| }, | |
| ], | |
| "MARKETING": [ | |
| { | |
| "scenario": "A local bakery in Hyderabad has great reviews but almost no online presence. They want to attract customers aged 20–35 who discover food businesses on Instagram. Their budget is zero — only organic content.", | |
| "task": "Write an AI prompt that helps them create a content strategy or specific post.", | |
| }, | |
| { | |
| "scenario": "An edtech startup is launching a new course on AI for non-technical professionals. They need to send a launch email to their existing subscriber list of 5,000 people — most of whom haven't opened emails in 3 months.", | |
| "task": "Write an AI prompt that produces this re-engagement launch email.", | |
| }, | |
| { | |
| "scenario": "A fitness trainer wants to run Google Ads for their personal training services in Mumbai. They have a ₹10,000/month budget and have never run paid ads before. Their USP is online coaching with personalised meal plans.", | |
| "task": "Write an AI prompt that helps them set up or plan this campaign effectively.", | |
| }, | |
| { | |
| "scenario": "A sustainable clothing brand is launching a new line made from recycled ocean plastic. Their target customer cares about the environment but is price-sensitive (products are 30% more expensive than fast fashion).", | |
| "task": "Write an AI prompt that creates compelling product description copy for their website.", | |
| }, | |
| ], | |
| "FINANCE": [ | |
| { | |
| "scenario": "A 28-year-old software developer earns ₹1.2 lakh per month but saves almost nothing. They have ₹3 lakh in credit card debt at 36% annual interest and no investments. They want to start getting their finances in order.", | |
| "task": "Write an AI prompt that produces a practical financial plan for this person.", | |
| }, | |
| { | |
| "scenario": "A small business owner wants to understand their company's cash flow statement. Their accountant gave them a document but they don't understand why the business is profitable on paper but always short on cash.", | |
| "task": "Write an AI prompt that explains this concept in a way they can immediately apply to their situation.", | |
| }, | |
| { | |
| "scenario": "A couple wants to save for their child's higher education. The child is currently 3 years old and they estimate they'll need ₹30 lakhs in 15 years. They can invest ₹10,000 per month.", | |
| "task": "Write an AI prompt that helps them understand their investment options and whether their goal is achievable.", | |
| }, | |
| { | |
| "scenario": "A salaried employee received their first Form 16 and has to file their ITR for the first time. They are confused about which ITR form to use, what deductions they can claim under 80C, and how to avoid mistakes.", | |
| "task": "Write an AI prompt that guides them through this process.", | |
| }, | |
| ], | |
| "CREATIVE": [ | |
| { | |
| "scenario": "A screenwriter wants to write a 5-minute short film about loneliness in a big city. The protagonist is a 30-year-old delivery driver who interacts with dozens of people every day but has no real relationships.", | |
| "task": "Write an AI prompt that helps develop this concept into a concrete scene or script outline.", | |
| }, | |
| { | |
| "scenario": "A startup founder needs to write the 'About Us' page for their company website. The company builds AI tools for teachers. The tone should feel human and mission-driven, not corporate or salesy.", | |
| "task": "Write an AI prompt that produces this About Us page.", | |
| }, | |
| { | |
| "scenario": "A children's book author wants to write a short story for 6–8 year olds that teaches them about the importance of asking for help — without being preachy. The story should have an animal character.", | |
| "task": "Write an AI prompt that generates this story or a strong outline for it.", | |
| }, | |
| { | |
| "scenario": "A musician wants to write lyrics for an indie-folk song about their grandmother who passed away last year. The mood should be bittersweet — celebrating her life rather than mourning — with imagery from her kitchen and garden.", | |
| "task": "Write an AI prompt that helps generate these lyrics or a draft verse.", | |
| }, | |
| ], | |
| } | |
| # ── Core functions ──────────────────────────────────────────────────────────── | |
| def get_scenario(domain): | |
| if not domain: | |
| return "", "" | |
| scenarios = SCENARIOS.get(domain, []) | |
| if not scenarios: | |
| return "", "" | |
| picked = random.choice(scenarios) | |
| scenario_html = f""" | |
| <div style="background:#0f172a;border-radius:10px;padding:20px 22px; | |
| border-left:4px solid #6366f1;font-family:sans-serif"> | |
| <div style="color:#a5b4fc;font-size:11px;font-weight:700; | |
| letter-spacing:.1em;margin-bottom:10px"> | |
| 📋 YOUR SCENARIO | |
| </div> | |
| <div style="color:#e2e8f0;font-size:15px;line-height:1.75;margin-bottom:16px"> | |
| {picked['scenario']} | |
| </div> | |
| <div style="background:#1e293b;border-radius:8px;padding:12px 16px"> | |
| <span style="color:#fbbf24;font-weight:700;font-size:13px">🎯 Your Task: </span> | |
| <span style="color:#fde68a;font-size:14px">{picked['task']}</span> | |
| </div> | |
| <div style="margin-top:14px;color:#475569;font-size:12px;font-style:italic"> | |
| 💡 Tip: A strong prompt assigns a role to the AI, specifies the audience, | |
| defines the output format, and sets constraints. You figure out how — that's the assessment. | |
| </div> | |
| </div>""" | |
| return scenario_html, picked["scenario"] + " | Task: " + picked["task"] | |
| def get_tier(score): | |
| """score is always 0–10""" | |
| if score >= 7.1: return "🟢 Strong", "#22c55e" | |
| elif score >= 4.1: return "🟡 Developing", "#f59e0b" | |
| else: return "🔴 Weak", "#ef4444" | |
| def extract_scores(text): | |
| patterns = { | |
| 'c1': r'C1_Foundations:\s*([0-9.]+)', | |
| 'c2': r'C2_Design:\s*([0-9.]+)', | |
| 'c3': r'C3_OutputSpec:\s*([0-9.]+)', | |
| 'c4': r'C4_Domain:\s*([0-9.]+)', | |
| 'c5': r'C5_Ethics:\s*([0-9.]+)', | |
| 'c6': r'C6_Metacognition:\s*([0-9.]+)', | |
| 'final': r'Final_Score:\s*([0-9.]+)', | |
| } | |
| return {k: float(m.group(1)) if (m := re.search(p, text)) else None | |
| for k, p in patterns.items()} | |
| def grade_prompt_fast(prompt_text, domain): | |
| input_text = ( | |
| f"Instruct: ### PELS Grading Task\n" | |
| f"Domain: {domain}\n" | |
| f"Rubric:\n{RUBRIC}\n\n" | |
| f"Candidate Prompt:\n{prompt_text}\n\n" | |
| f"### Evaluation\n" | |
| f"Score each category 1–10. Ethics score of 1 overrides all others.\n" | |
| f"Output:" | |
| ) | |
| inputs = tokenizer( | |
| input_text, return_tensors='pt', | |
| truncation=True, max_length=MAX_LENGTH | |
| ).to(model.device) | |
| with torch.no_grad(): | |
| outputs = model.generate( | |
| **inputs, | |
| max_new_tokens=MAX_NEW_TOKENS, | |
| do_sample=False, | |
| pad_token_id=tokenizer.eos_token_id, | |
| ) | |
| decoded = tokenizer.decode(outputs[0], skip_special_tokens=True) | |
| out_part = decoded[len(input_text):] if input_text in decoded else decoded | |
| return out_part, extract_scores(out_part) | |
| def build_score_html(scores, veto, raw_output): | |
| final = scores.get("final") or 0.0 | |
| final_display = final if final > 1.0 else final * 10 | |
| bar_pct = min(int(final_display * 10), 100) | |
| t_label, color = get_tier(final_display) | |
| cat_info = [ | |
| ("c1", "C1 · Foundations", "15%"), | |
| ("c2", "C2 · Design", "20%"), | |
| ("c3", "C3 · Output Spec", "20%"), | |
| ("c4", "C4 · Domain Application", "20%"), | |
| ("c5", "C5 · Ethics", "15%"), | |
| ("c6", "C6 · Metacognition", "10%"), | |
| ] | |
| rows = "" | |
| for key, label, weight in cat_info: | |
| val = scores.get(key) | |
| if val is None: | |
| rows += f"""<tr> | |
| <td style="padding:8px 12px;color:#94a3b8;font-family:sans-serif; | |
| white-space:nowrap">{label} <span style="color:#334155">({weight})</span></td> | |
| <td colspan="2" style="color:#475569;padding:8px 12px">—</td> | |
| </tr>""" | |
| continue | |
| val_d = val if val > 1.0 else val * 10 | |
| _, c = get_tier(val_d) | |
| pct = min(int(val_d * 10), 100) | |
| rows += f"""<tr> | |
| <td style="padding:8px 12px;font-weight:600;color:#cbd5e1; | |
| white-space:nowrap;font-family:sans-serif"> | |
| {label} <span style="color:#475569;font-weight:400">({weight})</span> | |
| </td> | |
| <td style="padding:8px 12px;width:100%"> | |
| <div style="background:#1e293b;border-radius:4px;height:13px;overflow:hidden"> | |
| <div style="background:{c};width:{pct}%;height:100%;border-radius:4px"></div> | |
| </div> | |
| </td> | |
| <td style="padding:8px 12px;font-weight:700;color:{c}; | |
| white-space:nowrap;font-family:sans-serif">{val_d:.1f}/10</td> | |
| </tr>""" | |
| veto_banner = "" | |
| if veto: | |
| veto_banner = """<div style="background:#7f1d1d;border:1px solid #dc2626; | |
| border-radius:8px;padding:10px 16px;margin-bottom:16px; | |
| color:#fca5a5;font-weight:600;font-family:sans-serif"> | |
| ⛔ Ethics Veto Triggered — Final Score overridden to 1.0 | |
| </div>""" | |
| just_match = re.search(r'Justification:\s*(.+)', raw_output, re.DOTALL) | |
| justification = just_match.group(1).strip()[:500] if just_match else "" | |
| just_html = "" | |
| if justification: | |
| just_html = f""" | |
| <div style="margin-top:20px;padding:14px 16px;background:#0f172a; | |
| border-left:3px solid #6366f1;border-radius:0 8px 8px 0"> | |
| <div style="color:#a5b4fc;font-size:11px;font-weight:700; | |
| letter-spacing:.08em;margin-bottom:8px;font-family:sans-serif"> | |
| JUSTIFICATION | |
| </div> | |
| <div style="color:#cbd5e1;line-height:1.7;font-size:14px;font-family:sans-serif"> | |
| {justification} | |
| </div> | |
| </div>""" | |
| return f""" | |
| <div style="font-family:sans-serif;background:#0f172a;border-radius:12px; | |
| padding:24px;color:#e2e8f0"> | |
| {veto_banner} | |
| <div style="display:flex;align-items:center;gap:24px;margin-bottom:24px"> | |
| <div style="text-align:center;min-width:90px"> | |
| <div style="font-size:54px;font-weight:800;color:{color};line-height:1"> | |
| {final_display:.1f} | |
| </div> | |
| <div style="font-size:12px;color:#64748b;margin-top:4px">out of 10</div> | |
| </div> | |
| <div style="flex:1"> | |
| <div style="background:#1e293b;border-radius:8px;height:20px;overflow:hidden"> | |
| <div style="background:{color};width:{bar_pct}%;height:100%;border-radius:8px"> | |
| </div> | |
| </div> | |
| <div style="margin-top:10px;font-size:17px;font-weight:700;color:{color}"> | |
| {t_label} | |
| </div> | |
| <div style="font-size:12px;color:#475569;margin-top:3px">PELS Final Score</div> | |
| </div> | |
| </div> | |
| <table style="width:100%;border-collapse:collapse;font-size:14px">{rows}</table> | |
| {just_html} | |
| </div>""" | |
| # ── Handlers ────────────────────────────────────────────────────────────────── | |
| def on_domain_change(domain): | |
| html, context = get_scenario(domain) | |
| return html, context, "", PLACEHOLDER | |
| def on_new_scenario(domain): | |
| html, context = get_scenario(domain) | |
| return html, context, "", PLACEHOLDER | |
| def evaluate(domain, user_prompt, scenario_context): | |
| if not domain: | |
| return "<p style='color:#f87171;font-family:sans-serif'>⚠️ Please select a domain first.</p>" | |
| if not user_prompt or len(user_prompt.strip()) < 10: | |
| return "<p style='color:#f87171;font-family:sans-serif'>⚠️ Please write your prompt (at least 10 characters).</p>" | |
| try: | |
| raw, scores = grade_prompt_fast(user_prompt.strip(), domain) | |
| except Exception as e: | |
| return f"<p style='color:#f87171;font-family:sans-serif'>❌ Error: {e}</p>" | |
| if not scores or all(v is None for v in scores.values()): | |
| return f"""<div style='padding:16px;background:#1e293b;border-radius:8px; | |
| color:#cbd5e1;font-family:sans-serif'> | |
| <b>Raw model output:</b><br> | |
| <pre style='white-space:pre-wrap;font-size:12px;color:#94a3b8'>{raw[:600]}</pre> | |
| <small style='color:#64748b'>Scores not parsed. Try a more detailed prompt.</small> | |
| </div>""" | |
| veto = (scores.get("c5") or 10) <= 1.0 | |
| if veto: | |
| scores["final"] = 1.0 | |
| return build_score_html(scores, veto, raw) | |
| def clear_all(): | |
| return None, "", "", PLACEHOLDER | |
| PLACEHOLDER = """ | |
| <div style='background:#0f172a;border-radius:12px;padding:40px; | |
| text-align:center;color:#334155;font-family:sans-serif;font-size:15px'> | |
| Your PELS score report will appear here after evaluation. | |
| </div>""" | |
| # ── UI ──────────────────────────────────────────────────────────────────────── | |
| with gr.Blocks(title="PELS Prompt Assessment", theme=gr.themes.Base()) as demo: | |
| scenario_context = gr.State("") # hidden state stores scenario text | |
| gr.HTML(""" | |
| <div style="padding:24px 0 12px"> | |
| <h1 style="font-family:sans-serif;font-size:2rem;font-weight:800;margin:0; | |
| background:linear-gradient(135deg,#6366f1,#a855f7,#ec4899); | |
| -webkit-background-clip:text;-webkit-text-fill-color:transparent"> | |
| PELS Prompt Assessment | |
| </h1> | |
| <p style="font-family:sans-serif;color:#64748b;margin:6px 0 0;font-size:14px"> | |
| You will receive a real-world scenario. Write an AI prompt to address it. | |
| Your prompt will be evaluated across 6 rubric categories. | |
| </p> | |
| </div>""") | |
| with gr.Row(): | |
| # ── Left ────────────────────────────────────────────────────────────── | |
| with gr.Column(scale=1): | |
| gr.HTML('<div style="font-family:sans-serif;font-weight:700;' | |
| 'color:#a5b4fc;font-size:12px;letter-spacing:.08em;' | |
| 'margin-bottom:6px">STEP 1 · CHOOSE DOMAIN</div>') | |
| domain_dd = gr.Dropdown( | |
| choices=list(SCENARIOS.keys()), | |
| label="Domain", value=None, interactive=True, | |
| ) | |
| gr.HTML('<div style="font-family:sans-serif;font-weight:700;' | |
| 'color:#a5b4fc;font-size:12px;letter-spacing:.08em;' | |
| 'margin:18px 0 6px">STEP 2 · YOUR SCENARIO</div>') | |
| scenario_display = gr.HTML( | |
| value="""<div style='background:#0f172a;border-radius:10px; | |
| padding:20px;text-align:center;color:#334155; | |
| font-family:sans-serif'> | |
| Select a domain above to receive your scenario. | |
| </div>""" | |
| ) | |
| new_scenario_btn = gr.Button( | |
| "🔀 Get Different Scenario", variant="secondary", size="sm" | |
| ) | |
| gr.HTML('<div style="font-family:sans-serif;font-weight:700;' | |
| 'color:#a5b4fc;font-size:12px;letter-spacing:.08em;' | |
| 'margin:18px 0 6px">STEP 3 · WRITE YOUR PROMPT</div>') | |
| prompt_box = gr.Textbox( | |
| label="Your AI Prompt", | |
| placeholder="Based on the scenario above, write your AI prompt here…", | |
| lines=9, | |
| ) | |
| with gr.Row(): | |
| clear_btn = gr.Button("🗑 Clear", variant="secondary", size="sm") | |
| eval_btn = gr.Button("⚡ Evaluate", variant="primary", size="lg") | |
| gr.HTML(""" | |
| <div style="margin-top:14px;padding:12px 14px;background:#1e293b; | |
| border-radius:8px;font-size:12px;color:#64748b; | |
| font-family:sans-serif;line-height:1.8"> | |
| <b style="color:#94a3b8">Rubric weights:</b><br> | |
| C1 Foundations 15% · C2 Design 20% · C3 Output Spec 20%<br> | |
| C4 Domain 20% · C5 Ethics 15% · C6 Metacognition 10%<br><br> | |
| <b style="color:#94a3b8">Tiers:</b> | |
| 🟢 Strong ≥ 7.1 | |
| · 🟡 Developing 4.1–7.0 | |
| · 🔴 Weak ≤ 4.0 | |
| </div>""") | |
| # ── Right ───────────────────────────────────────────────────────────── | |
| with gr.Column(scale=1): | |
| gr.HTML('<div style="font-family:sans-serif;font-weight:700;' | |
| 'color:#a5b4fc;font-size:12px;letter-spacing:.08em;' | |
| 'margin-bottom:6px">STEP 4 · PELS SCORE REPORT</div>') | |
| result_html = gr.HTML(value=PLACEHOLDER) | |
| with gr.Accordion("📖 Rubric Reference", open=False): | |
| gr.Markdown(""" | |
| | Category | Weight | What it checks | | |
| |---|---|---| | |
| | C1 Foundations | 15% | Task clarity, role setup, AI awareness | | |
| | C2 Design | 20% | Prompt structure — few-shot, CoT, role+task+constraint patterns | | |
| | C3 Output Spec | 20% | Format, length, tone, structure constraints | | |
| | C4 Domain | 20% | Domain vocabulary and contextual accuracy | | |
| | C5 Ethics | 15% | No harmful or biased framing — score of 1 overrides the final score | | |
| | C6 Metacognition | 10% | Self-awareness, iteration design, fallback handling | | |
| """) | |
| # ── Events ──────────────────────────────────────────────────────────────── | |
| domain_dd.change( | |
| fn=on_domain_change, | |
| inputs=domain_dd, | |
| outputs=[scenario_display, scenario_context, prompt_box, result_html] | |
| ) | |
| new_scenario_btn.click( | |
| fn=on_new_scenario, | |
| inputs=domain_dd, | |
| outputs=[scenario_display, scenario_context, prompt_box, result_html] | |
| ) | |
| eval_btn.click( | |
| fn=evaluate, | |
| inputs=[domain_dd, prompt_box, scenario_context], | |
| outputs=result_html | |
| ) | |
| clear_btn.click( | |
| fn=clear_all, | |
| outputs=[domain_dd, scenario_display, prompt_box, result_html] | |
| ) | |
| demo.launch(share=True) |