Add a notebook renderer for QDK Learning multiple-choice questions - #3690
Add a notebook renderer for QDK Learning multiple-choice questions#3690Dhairya Patel (HABER7789) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Untrusted renderer content can reach Copilot, while payload and stale-output validation gaps can produce incorrect quiz behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an interactive, kernel-independent notebook renderer for QDK Learning quizzes.
Changes:
- Implements multiple-choice rendering, grading, retry, accessibility, and Copilot actions.
- Adds Python quiz authoring, validation, conversion, and baked-output tooling.
- Converts IQPE self-check content and integrates renderer builds and messaging.
File summaries
| File | Description |
|---|---|
source/vscode/tsconfig.json |
Separates renderer type-checking. |
source/vscode/src/notebookRenderer/tsconfig.json |
Configures renderer TypeScript checks. |
source/vscode/src/notebookRenderer/styles.css |
Styles quiz states and controls. |
source/vscode/src/notebookRenderer/schema.ts |
Defines payload and messaging contracts. |
source/vscode/src/notebookRenderer/rendering.ts |
Adds safe DOM helpers. |
source/vscode/src/notebookRenderer/rendererApi.d.ts |
Declares notebook renderer APIs. |
source/vscode/src/notebookRenderer/multipleChoice.ts |
Implements quiz interaction and grading. |
source/vscode/src/notebookRenderer/index.ts |
Activates rendering and manages lifecycle. |
source/vscode/src/notebookRenderer/css.d.ts |
Types CSS text imports. |
source/vscode/src/learning/notebookRendererMessaging.ts |
Bridges renderer actions to Copilot. |
source/vscode/src/learning/notebookExercises.ts |
Excludes quizzes from tracked activities. |
source/vscode/src/learning/index.ts |
Registers renderer messaging. |
source/vscode/resources/qdk-learning/utils/chemistry-qpe/verify_course.py |
Recognizes baked quiz cells. |
source/vscode/resources/qdk-learning/utils/chemistry-qpe/README.md |
Documents quiz conversion workflow. |
source/vscode/resources/qdk-learning/utils/chemistry-qpe/details_to_quiz.py |
Converts and rebakes quiz outputs. |
source/vscode/resources/qdk-learning/courses/chemistry-qpe/06-iterative-phase-estimation/_unit.py |
Registers IQPE quiz content. |
source/vscode/resources/qdk-learning/courses/chemistry-qpe/_learning_output.py |
Defines quiz payloads and fallbacks. |
source/vscode/package.json |
Registers and type-checks the renderer. |
source/vscode/build.mjs |
Builds the renderer and checks contracts. |
source/vscode/authoring-courses.md |
Documents quiz authoring. |
source/npm/qsharp/ux/qdk-theme.css |
Adds quiz theme colors. |
Review details
- Files reviewed: 19/22 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| for cell in notebook["cells"]: | ||
| source = "".join(cell["source"]) | ||
| outputs = cell.get("outputs", []) | ||
| position = 0 | ||
| for call in QUIZ_CALL.findall(source): | ||
| for quiz_id in QUIZ_ID.findall(call): | ||
| expected = _normalize_bundle( | ||
| emitter._lookup_quiz(quiz_id)._repr_mimebundle_() | ||
| ) | ||
| actual = ( | ||
| _normalize_bundle(outputs[position].get("data")) | ||
| if position < len(outputs) | ||
| else None | ||
| ) | ||
| if actual != expected: | ||
| stale.append(quiz_id) | ||
| position += 1 | ||
| return stale |
There was a problem hiding this comment.
🟡 Changes recommended
The stale-output checker misses deleted single-quiz calls, and the Copilot action omits the learner’s selected answer.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
source/vscode/resources/qdk-learning/utils/chemistry-qpe/details_to_quiz.py:328
- When the last
quiz(...)call is removed from a cell,idsis empty and this early return skips its existing baked output. The deleted question therefore remains visible while--checkreports the notebook as up to date; most generated quiz cells contain only one call, so this is a common deletion case. Detect cells that still contain the custom quiz MIME output even when no IDs remain, and report or clear those outputs.
ids = _cell_quiz_ids(cell)
if not ids:
continue
- Files reviewed: 20/23 changed files
- Comments generated: 1
- Review effort level: Balanced
| const posted = context.postAction({ | ||
| type: "qdk-learning/action", | ||
| rendererId: RENDERER_ID, | ||
| actionId: "why-wrong", | ||
| quizId: payload.cellId, | ||
| }); |
Each section of the IQPE chapter ends with a self-check question. Today it's a dropdown you click to reveal the answer. This turns those 12 into multiple choice questions a learner answers, gets marked on, and can retry.
application/vnd.qdk.learning+json_unit.py, so the notebook cell only saysquiz("id")details_to_quiz.pybakes a chapter's questions;--checkreports stale outputschema.tsand in_learning_output.pywith nothing linking them, socheckRendererContract()compares the two at build time and fails if a field name or the MIME type stops matching