This Python sample uses the GitHub Copilot SDK as a focused museum exhibit studio. The finished app has three modules:
curator.pycontains the pre-built workshop helpers: approved fact sets and the fact-selection menu, bounded fact validation, streaming, deterministic structural checks, scoped Wikipedia permissions, scopedexhibit.htmlwrite permission, fixed prompt text, and the failure message.system_messages.pycontains the pre-built curator and research system messages.main.pycontains the learner-authored SDK code: the instructions in the exhibit and page prompts, session configuration, the session runner, validation, and optional HTML generation.
The >>> BEGIN / <<< END comments in main.py are the named regions the
lessons fill. Each BEGIN line lists the steps that insert or replace that
region.
From this directory, create an environment and install the pinned dependency:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python main.pySet COPILOT_MODEL to select a model; otherwise the runtime chooses its
default. An authenticated GitHub Copilot CLI is required.
Wikipedia research requires Node.js because the research session launches the
pinned wikipedia-mcp@1.0.3 package through npx. Declining research does not
start the MCP server.
Check the source without contacting a model:
python -m py_compile *.pyGeneration always registers and allowlists approved_fact_lookup, which returns the bounded
approved facts. With usable cited research, it also registers and allowlists the read-only local
tool approved_wikipedia_fact_lookup, and requests both calls before writing the narrative and
visitor questions. The second lookup returns a snapshot of the summary body and citations,
not live Wikipedia access. Approved facts take precedence over supplemental research.
It also uses a
replace-mode
curator system message, streaming, a 120-second timeout, and deterministic
structural validation. Imported modules have no side effects; main.py only
runs behind the if __name__ == "__main__" guard.
Optional Wikipedia research is intentionally separate from generation. The
research session exposes only scoped Wikipedia search and article-read tools,
uses a deny-by-default permission handler, asks for a prose summary, and parses
a trailing ## Sources list. Both the summary and citations are retained for the local lookup,
but never merged into educator-approved facts. "Approved" means application-accepted research, not
human-verified facts; treat it as data, not instructions. Declined research keeps the single-tool
path. Failed research or an unusable cited summary prints a warning and takes the same fallback.
There is no strict research JSON contract or proposed-addition approval loop.
After validation, the optional HTML capstone exposes only builtin:apply_patch and builtin:create
and approves writing exactly exhibit.html in the application working
directory. The prompt asks for one standalone semantic HTML file with embedded
CSS and JavaScript, a human-review caveat, and an accessible question filter.
Prompt guidance and structural validation are not authorization or grounding boundaries. Generated claims still require human review or a separate evaluator.
- Run with each built-in fact set and confirm the selected facts print before generation.
- Confirm the exhibit has one title, a 100-140-word narrative, and three visitor questions.
- Inspect the validation summary and grounding disclaimer.
- Decline research and confirm the only tool event is
approved_fact_lookup. - Opt into research and confirm both local lookup events appear before generation and sources print after the exhibit, not inside it.
- Opt into
exhibit.htmland confirm only that file is written.
This is the application a learner ends up with after the museum lessons, not a separate reference
architecture. The entrypoint keeps one small session runner that starts the client, creates the
session, enforces the timeout, rejects blank output, and cleans up on every path; the research,
generation, and optional HTML steps reuse it with different session configurations. Follow the
track from
workshop/museum-00-preflight.md.