****Construction Worker Training Project (Initial Draft and Encoding
using Python Programming Language (code):****
****The AI Engineering Prompt is the sole ingestion method for:
****
****1.Initial ingestion, ****
****2. Design and ****
****3. Implementation of an****
###
## ****AI Engineering Prompt: ****
****“ what are the standards for compliance in residential and
commercial construction. Is there a standard set of credentials required
for working in the construction trades. Specifics for accreditation in
education and training in construction trades. This includes EPA and
OSHA subject matter expertise in required subjective and objective areas
of expertise for standard residential and commercial construction
projects. In doing so please tell me about testing and skillsets
requirements for millwright and millworkers. Use dataframes where
warranted. I want to develop an education and training agent for the
above mentioned career field. Standard testing design features and an
application interface using python programming language for creating a
set of testing platform. Any standard testing format and multiple choice
UI architecture will work. As we proceed I will want to create a data
warehouse and knowledge base for storing and managing project and
subproject data. Furthermore, we should be able to apply this agent to
other trades or professions with relative ease, for ingestion,
processing, production and of data necessary for operating the various
artifacts that will make up the modular design of this agent. Let’s
pursue a studious theme, that is both technology friendly and in line
with best practices. Buttons, colors and fonts should accentuate the
purpose of the work for this the training set is designed. I should be
able to identify the area of study, the standard training curriculum, a
standard completion time and follow the most consistent domestic and
international guidelines required. This will require use of Large
Language Model Interface integration, some embedding (pinecone, chroma
datastore) and means for both voice and text ingestion, processing and
output. Use LangChain, LangGraph or LangSmith libraries python
implementation. Final products will have undergone the CI/CD project
management, i.e., GitHub, Git, life-cycle management system. This should
get us started. As we continue we will add the ability to predict
outcomes based on performance using standard metrics for subject
professions. Okay, I’m glad to be working with you. It’s taken a few
days for me to put together this prompt mentally, so feel free to add
your perspectives and suggestions. I’m gonna walk across the street to
our neighborhood McDonalds for the fam’s early dinner. I’ll be back as
soon as possible to see which direction we’re headed. Thanks. Enjoy the
mental, computational, logical, mathematical workout. Have fun with its
creative feature delivery“. (Author: Darrell Hall, MD, MSCIS)****
###
###
### ****Awesome brief, Darrell — let’s get you a real foundation you can
build on. I’ve (1) mapped the core compliance standards &
credentials with citations, (2) added craft-specific skill/assessment
matrices (incl. millwright & millworker), and (3) delivered a
working Python starter pack (API + MCQ UI + CI) you can run
today.****
****Your tables are ready to view above (open the three DataFrames I
displayed). And here’s a downloadable starter project:****
****Download the starter repo (zip)****
****1) Compliance landscape (U.S.) — what “standard” means****
****Model building codes & energy****
****Residential: IRC (one- and two-family). Commercial: IBC.
Jurisdictions adopt specific editions; these pull in many referenced
standards. ++ICC
Digital Codes+1++****
****Electrical (all occupancies): NFPA 70 (NEC) —
design/installation benchmark. ++NFPA+1++****
****Accessibility: DOJ’s 2010 ADA Standards (civil rights law) + ICC
A117.1 technical standard (often adopted via IBC). (Recent news removed
some non-binding DOJ guidance, but ADA law & 2010 Standards remain.)
++AP
News+5ADA.gov+5access-board.gov+5++****
****Worker safety (training you’ll test on)****
****OSHA 29 CFR 1926 (construction); OSHA 1910 for shops/fabs. OSHA
Outreach 10-hour/30-hour cards are widely required (not “licenses”).
++OSHA+3OSHA+3OSHA+3++****
****Environmental (you’ll want explicit modules &
checklists)****
****Lead (pre-1978): EPA RRP — firm cert + certified renovator +
lead-safe work practices + records. ++EPA+1++****
****Stormwater: EPA 2022 CGP (NPDES) — SWPPP, inspections, NOI/NOT;
some states run their own CGP. ++EPA+2EPA+2++****
****Specialty quality programs (commercial interiors)****
⚠️ Licensure/contractor cards are state-specific (GC,
electrical, mechanical, etc.). Treat state boards/AHJs as sources of
truth during onboarding.
****2) Credentials & accreditation (who issues what)****
****OSHA Outreach (10/30) — entry vs. supervisory safety awareness;
delivered by authorized trainers. ++OSHA+1++****
****EPA RRP Certified Renovator + Certified Firm — required for
paint-disturbing work in pre-1978 homes/child-occupied facilities. ++EPA+1++****
****The Credentials & Training Programs DataFrame (above)
consolidates this for your agent’s catalog.****
****3) Craft specifics — millwrights & millworkers (skills +
testing)****
****Millwright (industrial/construction mechanics)****
****Core skills you should test & observe: precision
layout/metrology, shaft alignment (dial & laser), baseplate setting
& grouting, rigging/hoisting planning, assembly
(bearings/couplings/gearboxes), print reading (P&IDs, GD&T
basics), commissioning (vibration baselines).****
****Millworker (architectural woodwork/casework)****
****The two skills matrices (Millwright & Millworker) are in the
DataFrames I posted to your workspace.****
****4) What I built for you (today)****
****Starter repo (FastAPI backend + Streamlit MCQ UI +
CI):
Download: construction_training_agent_starter.zip****
****Backend (FastAPI): /api/questions (list, filter by tag),
/api/questions/grade (grades submissions).****
****Frontend (Streamlit): studious theme, filter by tag,
radio-button MCQs, “Grade” with metrics.****
****CI: GitHub Actions workflow runs backend tests.****
****Samples: OSHA/EPA/millwright/millwork questions seeded.****
****Roadmap hooks already in requirements for LangChain, LangGraph,
Chroma, Pinecone.****
****Quickstart****
****5) Product blueprint (so we can scale to any trade)****
****A. Curriculum/standards registry (data warehouse)****
****Tables (suggested)****
****standards(area, code, edition, jurisdiction,
citation_url)****
****credentials(name, issuer, hours, renewal, applies_to)****
****skills(craft, skill, observable, tolerance, reference)****
****questions(id, stem, choices[], answer_id, tags[],
refs[])****
****attempts(user_id, question_id, chosen, correct,
latency_ms)****
****rubrics(task_id, criteria, scale, pass_threshold)****
****Storage: Postgres for OLTP; parquet+DuckDB or S3/Lake for
analytics; optional Snowflake/BigQuery later.****
****B. LLM/RAG layer****
****Ingest ADA/ICC/NFPA/EPA/OSHA summaries, state boards, AWI/NCCER
docs into a Chroma (local) or Pinecone (managed) vector store—chunked
with citations & edition metadata.****
****LangChain pipelines: retrieval-augmented explanations, code
lookup (“which IECC section applies?”), and question generation from
standards sections.****
****LangGraph for tool-use choreography (retrieve → draft → cite →
validate).****
****Guardrails: always surface edition + jurisdiction in answers;
link to primary source.****
****C. Testing & skills****
****Question bank: MCQ, scenario vignettes, image-based safety
checks, and performance checklists (e.g., “pump alignment
check-off”).****
****Rubrics: numeric tolerances for millwright tasks; AWI tolerances
for millwork installations.****
****Adaptive testing (IRT-lite): raise/lower difficulty by tag;
target minimum competency per credential.****
****D. Voice & multimodal****
****ASR (e.g., Whisper) for hands-busy quizzes; TTS for
feedback.****
****Image uploads (scaffold/plank setups, rigging gear) to evaluate
OSHA compliance checklists (human-in-the-loop).****
****E. CI/CD & DevOps****
****GitHub Actions: lint/test, build containers, deploy to
staging.****
****IaC later (Terraform) + secrets via GitHub OIDC.****
****Add OpenAPI schema checks and contract tests for the
front-end.****
****F. UI guidelines (studious theme)****
****Palette: deep blue (primary), green (success), amber
(warning).****
****Controls: Ingest, Process, Map (for network diagrams/learning
paths), Assess, Certify.****
****Surfaced info on every screen: Area of Study, Curriculum,
Estimated Completion Time, Standards/Edition, Jurisdiction.****
****6) What to add next (fast wins)****
****RAG answers + citations inside the MCQ app (LangChain Retriever
→ answer → show source).****
****Role-based views: Apprentice vs. Supervisor vs. Admin (adds
30-hour content, SWPPP tasks, etc.).****
****Performance module: enter dial indicator readings; auto-flag
tolerances out of range.****
****State packager: pick a state → it composes the right licensing
& adopted code editions.****
****Prediction: simple model from attempts + task rubric scores to
estimate time-to-competency and pass probability for a target
credential.****
****If you want, I’ll expand the repo with:****
****A RAG service (Chroma+LangChain) pre-loaded with briefings for
OSHA 1926, RRP, NESHAP/AHERA, IECC, ADA/A117.1, AWI QCP (with edition
tags).****
****A richer millwright practical module that records alignment
steps & computes pass/fail against tolerances.****
****CONSTRUCTION CODES:****
| Building & Residential Codes |
|
|
|
|
|
Building & Residential Codes |
ICC IBC / IRC (latest adopted by jurisdiction) |
Residential & Commercial |
Structural, fire & life safety, egress, materials, mechanical,
plumbing; local adoption controls edition. |
| Electrical |
|
|
|
|
|
Electrical |
NFPA 70 (NEC) |
Residential, Commercial, Industrial |
Design, installation, inspection of electrical systems; enforced by
AHJ/electrical inspector. |
| Energy |
|
|
|
|
|
Energy |
IECC (Residential & Commercial) |
Residential & Commercial |
Envelope, HVAC, lighting power, commissioning (Cx) requirements;
performance/prescriptive paths. |
| Accessibility |
|
|
|
|
|
Accessibility |
ADA 2010 Standards; ICC A117.1 |
Commercial & Public; some state/local overlays |
Accessible routes, clearances, bathrooms, signage; scoping via
IBC/ADA; technical via A117.1. |
| OSHA Safety (Construction) |
|
|
|
|
|
OSHA Safety (Construction) |
29 CFR 1926 |
Construction sites |
Fall protection, scaffolds, cranes, excavation, PPE, hazard comm,
training requirements. |
| OSHA Safety (General Industry) |
|
|
|
|
|
OSHA Safety (General Industry) |
29 CFR 1910 |
Shops, prefabrication, facilities |
Machine guarding, LOTO, electrical safety-related work practices,
respiratory protection. |
| Lead Paint (Pre-1978) |
|
|
|
|
|
Lead Paint (Pre-1978) |
EPA RRP Rule (40 CFR 745 Subpart E) |
Renovation in pre-1978 homes/child-occupied facilities |
Firm certification, renovator training, lead-safe work practices,
recordkeeping, occupant protection. |
| Asbestos (Renovation/Demo) |
|
|
|
|
|
Asbestos (Renovation/Demo) |
EPA NESHAP (40 CFR 61 Subpart M) + AHERA/MAP (40 CFR 763) |
Public/Commercial buildings; some residential demos |
Survey/inspection, notification (typically 10 business days),
accredited personnel, waste controls. |
| Stormwater |
|
|
|
|
|
Stormwater |
EPA NPDES 2022 Construction General Permit (CGP) |
Sites ≥ 1 acre disturbance (or part of common plan) |
SWPPP, erosion/sediment controls, inspections, NOI/NOT filings;
state CGPs or EPA CGP. |
| Fire/Life Safety |
|
|
|
|
|
Fire/Life Safety |
NFPA codes (e.g., NFPA 101), local fire code |
Residential & Commercial |
Egress, alarms, sprinklers, fire-resistance ratings; AHJ
approval. |
| Quality Woodwork (Commercial Interiors) |
|
|
|
|
|
Quality Woodwork (Commercial Interiors) |
AWI Standards & QCP |
Architectural woodwork/millwork |
Shop drawings, fabrication tolerances, finishes, certification of
fabricator/installer. |
****CREDENTIALS****
| OSHA 10-Hour (Construction) |
OSHA Outreach (via authorized providers) |
Entry-level workers |
10 hours |
Basic hazard recognition; voluntary but widely required by
owners/GCs. |
| OSHA 30-Hour (Construction) |
OSHA Outreach (via authorized providers) |
Leads/supervisors |
30 hours |
Deeper safety topics; recordkeeping, leadership; often required for
foremen. |
| EPA RRP Certified Renovator |
EPA or EPA-authorized State |
Renovators disturbing lead paint (pre-1978) |
8 hours + 5-year refresher |
Hands-on lead-safe practices; firm must also be certified. |
| Asbestos Accreditation (MAP) |
EPA/AHERA via state programs |
Inspector, Mgmt Planner, Project Designer, Supervisor, Worker |
Discipline-specific courses (e.g., Worker 4 days) + annual
refreshers |
Required for asbestos work in schools & most
public/commercial. |
| NCCER Core + Craft Credentials |
NCCER |
Apprentices & journeyworkers |
Varies by craft (modular) |
Portable credentials; knowledge & performance verified; widely
recognized. |
| Registered Apprenticeship |
USDOL Office of Apprenticeship / State |
New entrants in trades |
1–5 years (paid OJT + related instruction) |
Industry-vetted standards; progressive wage; nationally portable
credential. |
| AWI QCP Licensing |
Architectural Woodwork Institute |
Millwork fabricators/installers |
Application + audits |
Demonstrates compliance with AWI Standards on specified
projects. |
****MILLWRIGHT SKILL AND PERFORMANCE MATRIX****
| Precision Layout & Metrology |
|
|
|
|
Precision Layout & Metrology |
Demonstrate use of levels, micrometers, dial indicators |
±0.001–0.003 in where specified; document readings |
| Shaft Alignment (conventional/laser) |
|
|
|
|
Shaft Alignment (conventional/laser) |
Align pump-motor set using rim & face/laser |
Parallel & angular misalignment within manufacturer
tolerances |
| Baseplate & Grouting |
|
|
|
|
Baseplate & Grouting |
Set & grout base; verify elevation and flatness |
Flatness per spec; grout placement & cure per data sheet |
| Rigging & Hoisting |
|
|
|
|
Rigging & Hoisting |
Plan lift; select slings; execute safely |
OSHA 1926 Subpart CC compliance; load charts used; correct
signals |
| Mechanical Assembly |
|
|
|
|
Mechanical Assembly |
Install bearings, couplings, gearboxes |
Proper fits/torques; lubrication; runout within spec |
| Blueprints & Specs |
|
|
|
|
Blueprints & Specs |
Interpret P&IDs, isometrics, GD&T basics |
Accurate takeoffs; tolerance compliance |
| PM & Commissioning |
|
|
|
|
PM & Commissioning |
Pre-start checks; vibration baseline; alignment re-check |
Start-up checklist complete; vibration within baseline |
****MILLWORKER ARCHITECTURA WOODWORK SKILLS_MATRIX****
| Shop Drawings |
|
|
|
|
Shop Drawings |
Translate architect/engineer intent to shop drawings |
AWI compliance; field-verified dimensions |
| Joinery & Casework |
|
|
|
|
Joinery & Casework |
Fabricate cabinet/case to spec |
Tolerances per AWI; edges, reveals, squareness within spec |
| Finish & Veneer |
|
|
|
|
Finish & Veneer |
Apply specified finish/veneer |
Color/ sheen match; adhesion tests; AWI finish system rating |
| Installation |
|
|
|
|
Installation |
Install millwork per drawings |
Plumb/level; fastener concealment; scribe to walls within
tolerance |
| CNC & Tooling |
|
|
|
|
CNC & Tooling |
Program & operate CNC safely |
Correct feeds/speeds; tooling selection; QA of parts |
| Safety & Dust Control |
|
|
|
|
Safety & Dust Control |
Use guards, dust collection, PPE |
OSHA 1910/1926 compliant; exposure control (silica, wood dust) |
****# Let’s build structured DataFrames and a starter project zip
for the user.****
****import pandas as pd****
****from caas_jupyter_tools import
display_dataframe_to_user****
****import os, json, zipfile, textwrap****
****# 1) Standards & Codes matrix (high-level, not
exhaustive)****
****standards_data = [****
**** [“Building & Residential Codes”, “ICC IBC / IRC (latest
adopted by jurisdiction)”, “Residential & Commercial”, ****
**** “Structural, fire & life safety, egress, materials,
mechanical, plumbing; local adoption controls edition.”],****
**** [“Electrical”, “NFPA 70 (NEC)”, “Residential, Commercial,
Industrial”, ****
**** “Design, installation, inspection of electrical systems;
enforced by AHJ/electrical inspector.”],****
**** [“Energy”, “IECC (Residential & Commercial)”, “Residential
& Commercial”,****
**** “Envelope, HVAC, lighting power, commissioning (Cx)
requirements; performance/prescriptive paths.”],****
**** [“Accessibility”, “ADA 2010 Standards; ICC A117.1”, “Commercial
& Public; some state/local overlays”,****
**** “Accessible routes, clearances, bathrooms, signage; scoping via
IBC/ADA; technical via A117.1.”],****
**** [“OSHA Safety (Construction)”, “29 CFR 1926”, “Construction
sites”, ****
**** “Fall protection, scaffolds, cranes, excavation, PPE, hazard
comm, training requirements.”],****
**** [“OSHA Safety (General Industry)”, “29 CFR 1910”, “Shops,
prefabrication, facilities”, ****
**** “Machine guarding, LOTO, electrical safety-related work
practices, respiratory protection.”],****
**** [“Lead Paint (Pre-1978)”, “EPA RRP Rule (40 CFR 745 Subpart
E)”, “Renovation in pre-1978 homes/child-occupied facilities”, ****
**** “Firm certification, renovator training, lead-safe work
practices, recordkeeping, occupant protection.”],****
**** [“Asbestos (Renovation/Demo)”, “EPA NESHAP (40 CFR 61 Subpart
M) + AHERA/MAP (40 CFR 763)”, “Public/Commercial buildings; some
residential demos”, ****
**** “Survey/inspection, notification (typically 10 business days),
accredited personnel, waste controls.”],****
**** [“Stormwater”, “EPA NPDES 2022 Construction General Permit
(CGP)”, “Sites ≥ 1 acre disturbance (or part of common plan)”, ****
**** “SWPPP, erosion/sediment controls, inspections, NOI/NOT
filings; state CGPs or EPA CGP.”],****
**** [“Fire/Life Safety”, “NFPA codes (e.g., NFPA 101), local fire
code”, “Residential & Commercial”, ****
**** “Egress, alarms, sprinklers, fire-resistance ratings; AHJ
approval.”],****
**** [“Quality Woodwork (Commercial Interiors)”, “AWI Standards
& QCP”, “Architectural woodwork/millwork”, ****
**** “Shop drawings, fabrication tolerances, finishes, certification
of fabricator/installer.”]****
****]****
****standards_df = pd.DataFrame(standards_data, columns=[“Area”,
“Standard/Authority”, “Applies to”, “Key requirements”])****
****display_dataframe_to_user(“Construction Codes & Compliance
Matrix”, standards_df)****
****# 2) Credentials & Training Programs matrix****
****credentials_data = [****
**** [“OSHA 10-Hour (Construction)”, “OSHA Outreach (via authorized
providers)”, “Entry-level workers”, “10 hours”, ****
**** “Basic hazard recognition; voluntary but widely required by
owners/GCs.”],****
**** [“OSHA 30-Hour (Construction)”, “OSHA Outreach (via authorized
providers)”, “Leads/supervisors”, “30 hours”, ****
**** “Deeper safety topics; recordkeeping, leadership; often
required for foremen.”],****
**** [“EPA RRP Certified Renovator”, “EPA or EPA-authorized State”,
“Renovators disturbing lead paint (pre-1978)”, “8 hours + 5-year
refresher”, ****
**** “Hands-on lead-safe practices; firm must also be
certified.”],****
**** [“Asbestos Accreditation (MAP)”, “EPA/AHERA via state
programs”, “Inspector, Mgmt Planner, Project Designer, Supervisor,
Worker”, ****
**** “Discipline-specific courses (e.g., Worker 4 days) + annual
refreshers”, “Required for asbestos work in schools & most
public/commercial.”],****
**** [“NCCER Core + Craft Credentials”, “NCCER”, “Apprentices &
journeyworkers”, “Varies by craft (modular)”, ****
**** “Portable credentials; knowledge & performance verified;
widely recognized.”],****
**** [“Registered Apprenticeship”, “USDOL Office of Apprenticeship /
State”, “New entrants in trades”, “1–5 years (paid OJT + related
instruction)”, ****
**** “Industry-vetted standards; progressive wage; nationally
portable credential.”],****
**** [“AWI QCP Licensing”, “Architectural Woodwork Institute”,
“Millwork fabricators/installers”, “Application + audits”, ****
**** “Demonstrates compliance with AWI Standards on specified
projects.”],****
****]****
****credentials_df = pd.DataFrame(credentials_data,
columns=[“Credential”, “Issuer”, “Audience”, “Typical Length”,
“Notes”])****
****display_dataframe_to_user(“Credentials & Training Programs”,
credentials_df)****
****# 3) Millwright & Millworker skills/testing
matrices****
****millwright_data = [****
**** [“Precision Layout & Metrology”, “Demonstrate use of
levels, micrometers, dial indicators”, “±0.001–0.003 in where specified;
document readings”],****
**** [“Shaft Alignment (conventional/laser)”, “Align pump-motor set
using rim & face/laser”, “Parallel & angular misalignment within
manufacturer tolerances”],****
**** [“Baseplate & Grouting”, “Set & grout base; verify
elevation and flatness”, “Flatness per spec; grout placement & cure
per data sheet”],****
**** [“Rigging & Hoisting”, “Plan lift; select slings; execute
safely”, “OSHA 1926 Subpart CC compliance; load charts used; correct
signals”],****
**** [“Mechanical Assembly”, “Install bearings, couplings,
gearboxes”, “Proper fits/torques; lubrication; runout within
spec”],****
**** [“Blueprints & Specs”, “Interpret P&IDs, isometrics,
GD&T basics”, “Accurate takeoffs; tolerance compliance”],****
**** [“PM & Commissioning”, “Pre-start checks; vibration
baseline; alignment re-check”, “Start-up checklist complete; vibration
within baseline”]****
****]****
****millwright_df = pd.DataFrame(millwright_data,
columns=[“Skill/Task”, “Performance Test”, “Acceptance
Criteria”])****
****display_dataframe_to_user(“Millwright Skill & Performance
Matrix”, millwright_df)****
****millworker_data = [****
**** [“Shop Drawings”, “Translate architect/engineer intent to shop
drawings”, “AWI compliance; field-verified dimensions”],****
**** [“Joinery & Casework”, “Fabricate cabinet/case to spec”,
“Tolerances per AWI; edges, reveals, squareness within spec”],****
**** [“Finish & Veneer”, “Apply specified finish/veneer”,
“Color/ sheen match; adhesion tests; AWI finish system
rating”],****
**** [“Installation”, “Install millwork per drawings”, “Plumb/level;
fastener concealment; scribe to walls within tolerance”],****
**** [“CNC & Tooling”, “Program & operate CNC safely”,
“Correct feeds/speeds; tooling selection; QA of parts”],****
**** [“Safety & Dust Control”, “Use guards, dust collection,
PPE”, “OSHA 1910/1926 compliant; exposure control (silica, wood
dust)”]****
****]****
****millworker_df = pd.DataFrame(millworker_data,
columns=[“Skill/Task”, “Performance Test”, “Acceptance
Criteria”])****
****display_dataframe_to_user(“Millworker (Architectural Woodwork)
Skills Matrix”, millworker_df)****
****# 4) Create a minimal, modular starter project (backend FastAPI
+ frontend Streamlit) with MCQ testing,****
****# embeddings hooks (Chroma/Pinecone), and room to grow with
LangChain/LangGraph.****
****base = “/mnt/data/construction_training_agent_starter”****
****os.makedirs(base, exist_ok=True)****
****# Directory structure****
****dirs = [****
**** “backend/routers”,****
**** “backend/tests”,****
**** “backend/data”,****
**** “frontend”,****
**** “.github/workflows”****
****]****
****for d in dirs:****
**** os.makedirs(os.path.join(base, d), exist_ok=True)****
****# Backend main.py****
****backend_main = textwrap.dedent(“““****
**** from fastapi import FastAPI****
**** from fastapi.middleware.cors import CORSMiddleware****
**** from routers import questions****
**** from pydantic import BaseModel****
**** import uvicorn****
**** ****
**** app = FastAPI(title=“Construction Training Agent API”,
version=“0.1.0”)****
**** app.add_middleware(****
**** CORSMiddleware,****
**** allow_origins=[“*”],****
**** allow_credentials=True,****
**** allow_methods=[“*”],****
**** )****
**** ****
**** app.include_router(questions.router, prefix=“/api/questions”,
tags=[“questions”])****
**** ****
**** class Health(BaseModel):****
**** status: str = “ok”****
**** ****
**** @app.get(“/health”,
response_model=Health)****
**** def health():****
**** return {“status”: “ok”}****
**** ****
**** if name == “main”:****
**** uvicorn.run(“main:app”, host=“0.0.0.0”, port=8000,
reload=True)****
****“““).strip()****
****# Routers: questions.py****
****backend_questions = textwrap.dedent(“““****
**** from fastapi import APIRouter, HTTPException****
**** from pydantic import BaseModel****
**** from typing import List, Optional, Dict, Any****
**** import json****
**** from pathlib import Path****
**** ****
**** router = APIRouter()****
**** DATA_PATH = Path(file).resolve().parents[1] /
“data” / “sample_questions.json”****
**** ****
**** class Choice(BaseModel):****
**** id: str****
**** text: str****
**** ****
**** class Question(BaseModel):****
**** id: str****
**** stem: str****
**** choices: List[Choice]****
**** answer_id: str****
**** tags: List[str] = []****
**** standard_refs: List[str] = []****
**** difficulty: str = “medium”****
**** ****
**** @router.get(“/”,
response_model=List[Question])****
**** def list_questions(tag: Optional[str] = None):****
**** data = json.loads(Path(DATA_PATH).read_text())****
**** if tag:****
**** data = [q for q in data if tag in q.get(“tags”, [])]****
**** return data****
**** ****
**** class Submission(BaseModel):****
**** responses: Dict[str, str] # {question_id:
chosen_choice_id}****
**** ****
**** class Grade(BaseModel):****
**** total: int****
**** correct: int****
**** score_pct: float****
**** breakdown: Dict[str, Any]****
**** ****
**** @router.post(“/grade”,
response_model=Grade)****
**** def grade(submission: Submission):****
**** data = {q[“id”]: q for q in
json.loads(Path(DATA_PATH).read_text())}****
**** total = len(submission.responses)****
**** correct = 0****
**** breakdown = {}****
**** for qid, choice in submission.responses.items():****
**** q = data.get(qid)****
**** if not q:****
**** continue****
**** is_correct = (choice == q[“answer_id”])****
**** correct += 1 if is_correct else 0****
**** breakdown[qid] = {“correct”: is_correct, “answer_id”:
q[“answer_id”]}****
**** score = (correct / total * 100) if total else 0.0****
**** return {“total”: total, “correct”: correct, “score_pct”:
round(score, 2), “breakdown”: breakdown}****
****“““).strip()****
****# Sample questions****
****sample_questions = [****
**** {****
**** “id”: “q1”,****
**** “stem”: “Which OSHA standard primarily governs construction
site safety?”,****
**** “choices”: [{“id”:“a”,“text”:“29 CFR 1910”},
{“id”:“b”,“text”:“29 CFR 1926”}, {“id”:“c”,“text”:“40 CFR 61 Subpart
M”}, {“id”:“d”,“text”:“NFPA 101”}],****
**** “answer_id”: “b”,****
**** “tags”: [“OSHA”,“construction”],****
**** “standard_refs”: [“29 CFR 1926”],****
**** “difficulty”: “easy”****
**** },****
**** {****
**** “id”: “q2”,****
**** “stem”: “Under the EPA RRP Rule, which projects require a
Certified Renovator?”,****
**** “choices”: [{“id”:“a”,“text”:“Any project in buildings built
after 1978”}, {“id”:“b”,“text”:“Projects disturbing lead paint in
pre-1978 child-occupied facilities”}, {“id”:“c”,“text”:“Any roofing
project”}, {“id”:“d”,“text”:“Landscaping only”}],****
**** “answer_id”: “b”,****
**** “tags”: [“EPA”,“lead”,“RRP”],****
**** “standard_refs”: [“40 CFR 745 Subpart E”],****
**** “difficulty”: “medium”****
**** },****
**** {****
**** “id”: “q3”,****
**** “stem”: “A pump-motor alignment is acceptable when shaft
misalignment is within:”,****
**** “choices”: [{“id”:“a”,“text”:“Manufacturer tolerances”},
{“id”:“b”,“text”:“±1/4 inch”}, {“id”:“c”,“text”:“Any value if vibration
is low”}, {“id”:“d”,“text”:“Only laser-aligned systems are
acceptable”}],****
**** “answer_id”: “a”,****
**** “tags”: [“millwright”,“mechanical”],****
**** “standard_refs”: [“Manufacturer O&M”],****
**** “difficulty”: “medium”****
**** },****
**** {****
**** “id”: “q4”,****
**** “stem”: “Which program certifies architectural woodwork quality
on specified projects?”,****
**** “choices”: [{“id”:“a”,“text”:“NCCER Core”},
{“id”:“b”,“text”:“AWI QCP”}, {“id”:“c”,“text”:“NEC”},
{“id”:“d”,“text”:“IECC”}],****
**** “answer_id”: “b”,****
**** “tags”: [“millwork”,“quality”],****
**** “standard_refs”: [“AWI QCP”],****
**** “difficulty”: “easy”****
**** }****
****]****
****# Frontend streamlit app****
****streamlit_app = textwrap.dedent(“““****
**** import streamlit as st****
**** import requests****
**** import random****
**** ****
**** st.set_page_config(page_title=“Construction Training – MCQ”,
page_icon=“🛠️”)****
**** ****
**** st.markdown("""****
### ****
**** """, unsafe_allow_html=True)****
**** ****
**** st.title(“🛠️ Construction Training – Multiple Choice”)****
**** st.caption(“Studious, tech-friendly theme • OSHA • EPA • Codes
• Millwright • Millwork”)****
**** ****
**** tag = st.selectbox(“Filter questions by tag (optional)”,
[““,”OSHA”, “EPA”, “RRP”, “construction”, “millwright”,
“millwork”])****
**** ****
**** if st.button(“🧊 Load Questions”):****
**** url = f”{api}/questions/“****
**** if tag:****
**** url += f”?tag={tag}“****
**** try:****
**** resp = requests.get(url, timeout=10)****
**** resp.raise_for_status()****
**** st.session_state.questions = resp.json()****
**** random.shuffle(st.session_state.questions)****
**** st.success(f”Loaded {len(st.session_state.questions)}
questions.”)****
**** except Exception as e:****
**** st.error(f”Failed to load: {e}“)****
**** ****
**** if “questions” in st.session_state and
st.session_state.questions:****
### **** st.markdown(’
Answer the questions and click Grade when done.
’, unsafe_allow_html=True)****
### **** answers = {}****
### **** for q in st.session_state.questions:****
### **** st.subheader(q[“stem”])****
### **** choice = st.radio(“Choose one:”, options=[c[“id”] for c in
q[“choices”]], format_func=lambda cid: next(c[“text”] for c in
q[“choices”] if c[“id”]==cid), key=f”q_{q[‘id’]}“)****
### **** answers[q[”id”]] = choice****
### **** with st.expander(”Refs & Tags”):****
### **** st.write(q.get(“standard_refs”, []), q.get(“tags”,
[]))****
### **** if st.button(“✅ Grade”):****
### **** try:****
### **** resp = requests.post(f”{api}/questions/grade”,
json={“responses”: answers})****
### **** resp.raise_for_status()****
### **** g = resp.json()****
### **** st.metric(“Score”, f”{g[‘score_pct’]}%“)****
### **** st.write(g[”breakdown”])****
### **** except Exception as e:****
### **** st.error(f”Failed to grade: {e}“)****
### **** else:****
### **** st.info(”Load questions to begin.”)****
### ****“““).strip()****
###
### ****# README****
### ****readme = textwrap.dedent(”““****
### **** # Construction Training Agent (Starter)****
###
### **** A modular starter for an education & testing platform
covering construction compliance (OSHA, EPA, codes), plus craft skills
(millwright, millwork).****
### **** ****
### **** ## Features****
### **** - FastAPI backend with MCQ endpoints****
### **** - Streamlit front-end for a quick
multiple-choice UI (studious theme)****
### **** - Sample questions with standards references****
### **** - Ready for LLM integration (LangChain/LangGraph), embeddings
(Chroma/Pinecone) hooks****
### **** - CI with GitHub Actions (pytest)****
### **** ****
### **** ## Quickstart****
### ****
bash**** ### **** # in one terminal**** ### **** cd backend**** ### **** python -m venv .venv && source .venv/bin/activate**** ### **** pip install -r requirements.txt**** ### **** uvicorn main:app --reload**** ### **** **** ### **** # in another terminal**** ### **** cd frontend**** ### **** python -m venv .venv && source .venv/bin/activate**** ### **** pip install -r requirements.txt**** ### **** streamlit run streamlit_app.py**** ### ********
### **** ****
### **** Open Streamlit, set API base to
http://localhost:8000/api and load questions.****
### **** ****
### **** ## Next steps****
### **** - Add role-based auth****
### **** - Add embeddings & RAG over code/standards (Chroma for
local, Pinecone for cloud)****
### **** - Add voice I/O (Whisper / SpeechRecognition + TTS) and LLM
evaluation****
### **** - Extend crafts and add performance assessments****
### ****”““).strip()****
###
### ****# Requirements****
### ****backend_requirements =”“.join([****
### **** ”fastapi>=0.112.0”,****
### **** ”uvicorn[standard]>=0.30.0”,****
### **** ”pydantic>=2.6.4”,****
### **** ”langchain>=0.2.0”,****
### **** ”langgraph>=0.1.0”,****
### **** ”chromadb>=0.5.0”,****
### **** ”pinecone-client>=5.0.0”,****
### **** ”sqlalchemy>=2.0.0”,****
### **** ”pytest>=8.0.0”,****
### **** ”httpx>=0.27.0”****
### ****])****
###
### ****frontend_requirements =”“.join([****
### **** ”streamlit>=1.36.0”,****
### **** ”requests>=2.32.0”****
### ****])****
###
### ****# CI workflow****
### ****ci_yaml = textwrap.dedent(”““****
### **** name: ci****
### **** on: [push, pull_request]****
### **** jobs:****
### **** test-backend:****
### **** runs-on: ubuntu-latest****
### **** steps:****
### **** - uses: actions/checkout@v4****
### **** - name: Set up Python****
### **** uses: actions/setup-python@v5****
### **** with:****
### **** python-version: ‘3.11’****
### **** - name: Install deps****
### **** run: |****
### **** cd backend****
### **** python -m pip install -r requirements.txt****
### **** - name: Run tests****
### **** run: |****
### **** cd backend****
### **** pytest -q****
### ****”““).strip()****
###
### ****# Backend test****
### ****backend_test = textwrap.dedent(”““****
### **** from fastapi.testclient import TestClient****
### **** from main import app****
### **** ****
### **** def test_health():****
### **** client = TestClient(app)****
### **** r = client.get(‘/health’)****
### **** assert r.status_code == 200****
### **** assert r.json()[‘status’] == ‘ok’****
### ****”““).strip()****
###
### ****# Write files****
### ****open(os.path.join(base,”backend”, “main.py”),
“w”).write(backend_main)****
### ****open(os.path.join(base, “backend”, “routers”, “questions.py”),
“w”).write(backend_questions)****
### ****open(os.path.join(base, “backend”, “requirements.txt”),
“w”).write(backend_requirements)****
### ****open(os.path.join(base, “backend”, “tests”,
“test_questions.py”), “w”).write(backend_test)****
### ****open(os.path.join(base, “backend”, “data”,
“sample_questions.json”), “w”).write(json.dumps(sample_questions,
indent=2))****
### ****open(os.path.join(base, “frontend”, “streamlit_app.py”),
“w”).write(streamlit_app)****
### ****open(os.path.join(base, “frontend”, “requirements.txt”),
“w”).write(frontend_requirements)****
### ****open(os.path.join(base, “.github”, “workflows”, “ci.yml”),
“w”).write(ci_yaml)****
### ****open(os.path.join(base, “README.md”),
“w”).write(readme)****
###
### ****# Zip it****
### ****zip_path =
“/mnt/data/construction_training_agent_starter.zip”****
### ****with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as
z:****
### **** for root, _, files in os.walk(base):****
### **** for f in files:****
### **** z.write(os.path.join(root, f),
arcname=os.path.relpath(os.path.join(root, f), start=base))****
###
### ****zip_path****
###
### ****# Terminal A****
### ****cd backend****
### ****python -m venv .venv && source
.venv/bin/activate****
### ****pip install -r requirements.txt****
### ****uvicorn main:app –reload****
###
### ****# Terminal B****
### ****cd frontend****
### ****python -m venv .venv && source
.venv/bin/activate****
### ****pip install -r requirements.txt****
### ****streamlit run streamlit_app.py****
###
### ****# In the app: set API base to http://localhost:8000/api****
###
###