microfactory-lab / scripts /scripted_demo.py
kylebrodeur's picture
Upload folder using huggingface_hub
6b09b49 verified
Raw
History Blame Contribute Delete
3.77 kB
"""Scripted demo / integration test β€” the Day-4/5 dry run, in code.
Runs a curated job sequence through the REAL loop (advise β†’ Spine β†’ reflect) on
a fresh seeded ledger and prints a readable transcript. It exists to (a) expose
demo-path bugs early β€” the step Kaggle never reached β€” and (b) be the source of
truth for the video beats: precedent applied, environment-driven shift, and the
"no close precedent" discrimination case.
Works offline (deterministic fallback) and gets richer with real Ollama.
Run: `make demo` (or `uv run python -m scripts.scripted_demo`)
"""
from __future__ import annotations
import sys
import tempfile
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) # repo root on path
from core.chief_engineer import advise
from core.ledger import LedgerManager
from core.models import Environment, Job, PrintSettings
from core.reflect import reflect_on_job
from core.seed_lessons import ensure_seeded
from core.spine import SpineValidator
SPINE = SpineValidator()
# (job, env, beat, outcome-to-record) β€” designed to make compounding legible.
SCENARIOS = [
(Job(geometry_type="overhang", material="PLA", description="45Β° bracket, 60mm tall"),
Environment(temp=28, humidity=50),
"Warm room β€” should match the prior PLA overhang that SAGGED at 28Β°C.",
"failed_sag"),
(Job(geometry_type="overhang", material="PLA", description="same bracket, cooler day"),
Environment(temp=23, humidity=40),
"Cooler/drier β€” recommendation should shift vs the warm run.",
"success"),
(Job(geometry_type="stringing", material="PETG", description="hex grid, lots of travel"),
Environment(temp=25, humidity=65),
"Humid PETG β€” precedent should suspect MOISTURE, not just retraction.",
"success"),
(Job(geometry_type="vase", material="TPU", description="flexible spiral vase"),
Environment(temp=22, humidity=45),
"NOVEL: no TPU/vase precedent β€” expect 'no close precedent' reasoning.",
None),
]
def _rule(label: str) -> None:
print(f"\n{'─' * 70}\n{label}\n{'─' * 70}")
def run() -> None:
led = LedgerManager(Path(tempfile.mkdtemp()) / "lessons.jsonl")
print(f"seeded {ensure_seeded(led)} lessons Β· ledger={led.count()}")
for i, (job, env, beat, outcome) in enumerate(SCENARIOS, 1):
_rule(f"JOB {i}: {job.material}/{job.geometry_type} @ {env.temp:.0f}Β°C/{env.humidity:.0f}% RH")
print(f" beat β†’ {beat}")
retrieved = led.retrieve(job.material, job.geometry_type, env.temp, env.humidity)
if retrieved:
print(" precedent:")
for e, d in retrieved:
print(f" β€’ {e.job_id} ({e.source}) {e.outcome} dist={d:.2f}")
else:
print(" precedent: (none β€” novel situation)")
rec = advise(job, env, retrieved)
s = rec.advice.settings
spine = SPINE.check(s, job.material)
print(f" backend: {rec.backend}{' [fallback]' if rec.used_fallback else ''}")
print(f" reasoning: {rec.advice.reasoning}")
print(f" settings: nozzle={spine.settings.nozzle_temp:.0f} bed={spine.settings.bed_temp:.0f} "
f"retr={spine.settings.retraction_mm:.1f} fan={spine.settings.fan_pct:.0f}%")
if spine.vetoes:
print(" πŸ›‘ spine:", "; ".join(spine.vetoes))
for r in rec.advice.risks:
print(f" ⚠ risk: {r.risk} @ {r.location} β€” {r.why}")
if outcome:
entry = reflect_on_job(job, env, spine.settings, outcome, led)
print(f" πŸ“’ recorded ({outcome}) β†’ earned: {entry.lesson}")
print(f"\nFINAL LEDGER: {led.count()} (knowledge compounded across the run)")
if __name__ == "__main__":
run()