This Python sample uses the GitHub Copilot SDK as a focused museum exhibit studio. The finished app now has two modules:
curator.pycontains the pre-built workshop helpers: approved fact sets, bounded fact validation, streaming, deterministic structural checks, scoped Wikipedia permissions, scopedexhibit.htmlwrite permission, and terminal helpers.main.pycontains the learner-authored orchestration: prompts, session configuration, console flow, validation, and optional HTML generation.
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.