Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
"""
|
| 2 |
-
NWFWO Practice
|
| 3 |
|
|
|
|
| 4 |
1) Runs a normal Gradio web app (for debugging in your browser)
|
| 5 |
2) Exposes an MCP server + HTML UI card for ChatGPT Apps
|
| 6 |
"""
|
|
@@ -11,7 +12,7 @@ from typing import Optional
|
|
| 11 |
import gradio as gr
|
| 12 |
|
| 13 |
|
| 14 |
-
# ---- 1. Data model for the
|
| 15 |
|
| 16 |
@dataclass
|
| 17 |
class NWFWOExample:
|
|
@@ -23,9 +24,16 @@ class NWFWOExample:
|
|
| 23 |
explanation: Optional[str] = None
|
| 24 |
|
| 25 |
|
| 26 |
-
# ---- 2. Core tool logic: check the learner
|
| 27 |
|
| 28 |
-
@gr.mcp.tool(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
def check_nwfwo(
|
| 30 |
transliteration: str,
|
| 31 |
correct_nwfwo: str,
|
|
@@ -70,7 +78,7 @@ def check_nwfwo(
|
|
| 70 |
return result
|
| 71 |
|
| 72 |
|
| 73 |
-
# ---- 3. Normal Gradio UI (handy while you
|
| 74 |
|
| 75 |
def local_check_ui(transliteration, correct_nwfwo, user_guess, explanation):
|
| 76 |
res = check_nwfwo(
|
|
@@ -128,6 +136,16 @@ with gr.Blocks() as demo:
|
|
| 128 |
outputs=[result_box],
|
| 129 |
)
|
| 130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
# ---- 4. HTML UI card resource for ChatGPT App ----
|
| 133 |
|
|
@@ -156,8 +174,8 @@ def nwfwo_html_card():
|
|
| 156 |
const userGuess = input.user_guess || output.user_guess || "salam";
|
| 157 |
const correctNwfwo = input.correct_nwfwo || output.correct_nwfwo || "salaam";
|
| 158 |
|
| 159 |
-
const isCorrect
|
| 160 |
-
const feedback
|
| 161 |
const explanation = output.explanation || "";
|
| 162 |
|
| 163 |
let badge = "";
|
|
@@ -214,6 +232,13 @@ def nwfwo_html_card():
|
|
| 214 |
}
|
| 215 |
|
| 216 |
render();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
</script>
|
| 218 |
"""
|
| 219 |
return html
|
|
@@ -222,8 +247,4 @@ def nwfwo_html_card():
|
|
| 222 |
# ---- 5. Main entrypoint ----
|
| 223 |
|
| 224 |
if __name__ == "__main__":
|
| 225 |
-
|
| 226 |
-
# mcp_server=True exposes the MCP endpoint (on /gradio_api/mcp/ in Spaces).
|
| 227 |
-
demo.launch(
|
| 228 |
-
mcp_server=True,
|
| 229 |
-
)
|
|
|
|
| 1 |
"""
|
| 2 |
+
NWFWO Practice β Gradio MCP app for ChatGPT
|
| 3 |
|
| 4 |
+
This file does two things:
|
| 5 |
1) Runs a normal Gradio web app (for debugging in your browser)
|
| 6 |
2) Exposes an MCP server + HTML UI card for ChatGPT Apps
|
| 7 |
"""
|
|
|
|
| 12 |
import gradio as gr
|
| 13 |
|
| 14 |
|
| 15 |
+
# ---- 1. Data model for the βgame stateβ ----
|
| 16 |
|
| 17 |
@dataclass
|
| 18 |
class NWFWOExample:
|
|
|
|
| 24 |
explanation: Optional[str] = None
|
| 25 |
|
| 26 |
|
| 27 |
+
# ---- 2. Core tool logic: check the learnerβs guess ----
|
| 28 |
|
| 29 |
+
@gr.mcp.tool(
|
| 30 |
+
_meta={
|
| 31 |
+
# Tell ChatGPT which widget template to use for this tool
|
| 32 |
+
"openai/outputTemplate": "ui://widget/nwfwo-practice-card.html",
|
| 33 |
+
"openai/resultCanProduceWidget": True,
|
| 34 |
+
"openai/widgetAccessible": True,
|
| 35 |
+
}
|
| 36 |
+
)
|
| 37 |
def check_nwfwo(
|
| 38 |
transliteration: str,
|
| 39 |
correct_nwfwo: str,
|
|
|
|
| 78 |
return result
|
| 79 |
|
| 80 |
|
| 81 |
+
# ---- 3. Normal Gradio UI (handy while youβre developing) ----
|
| 82 |
|
| 83 |
def local_check_ui(transliteration, correct_nwfwo, user_guess, explanation):
|
| 84 |
res = check_nwfwo(
|
|
|
|
| 136 |
outputs=[result_box],
|
| 137 |
)
|
| 138 |
|
| 139 |
+
# ---- (NEW) wire the MCP resource to a Gradio event ----
|
| 140 |
+
# This makes Gradio actually register the MCP resource.
|
| 141 |
+
widget_preview = gr.Code(
|
| 142 |
+
label="NWFWO widget HTML (for MCP)",
|
| 143 |
+
language="html",
|
| 144 |
+
visible=False,
|
| 145 |
+
)
|
| 146 |
+
# Call the resource once on load; enough to register it.
|
| 147 |
+
demo.load(fn=lambda: nwfwo_html_card(), inputs=None, outputs=widget_preview)
|
| 148 |
+
|
| 149 |
|
| 150 |
# ---- 4. HTML UI card resource for ChatGPT App ----
|
| 151 |
|
|
|
|
| 174 |
const userGuess = input.user_guess || output.user_guess || "salam";
|
| 175 |
const correctNwfwo = input.correct_nwfwo || output.correct_nwfwo || "salaam";
|
| 176 |
|
| 177 |
+
const isCorrect = output.is_correct;
|
| 178 |
+
const feedback = output.feedback || "";
|
| 179 |
const explanation = output.explanation || "";
|
| 180 |
|
| 181 |
let badge = "";
|
|
|
|
| 232 |
}
|
| 233 |
|
| 234 |
render();
|
| 235 |
+
|
| 236 |
+
// Good practice: re-render when ChatGPT updates tool globals
|
| 237 |
+
window.addEventListener("openai:set_globals", (event) => {
|
| 238 |
+
if (event.detail && event.detail.globals && event.detail.globals.toolOutput) {
|
| 239 |
+
render();
|
| 240 |
+
}
|
| 241 |
+
}, { passive: true });
|
| 242 |
</script>
|
| 243 |
"""
|
| 244 |
return html
|
|
|
|
| 247 |
# ---- 5. Main entrypoint ----
|
| 248 |
|
| 249 |
if __name__ == "__main__":
|
| 250 |
+
demo.launch(mcp_server=True)
|
|
|
|
|
|
|
|
|
|
|
|