Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -250,6 +250,80 @@ def compute_housing_per_acre(cost: float, acres: float) -> float:
|
|
| 250 |
# Housing = 0.5% of cost, allocated per acre
|
| 251 |
return 0.005 * float(cost) / max(float(acres), 1e-9)
|
| 252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
|
| 254 |
# ---- Keyword intent + Regex fallback ----
|
| 255 |
NUM=r"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?"
|
|
@@ -545,13 +619,28 @@ with gr.Blocks(css="footer {visibility: hidden}") as demo:
|
|
| 545 |
gr.Markdown("### Student HUD β what Jerry sees")
|
| 546 |
hud_box = gr.Textbox(label="Final Data (persists this session)", lines=18, value=_pp({k: None for k in HUD_FIELDS}))
|
| 547 |
changed_box = gr.Textbox(label="Fields updated by last prompt", lines=3, value="(none)")
|
| 548 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 549 |
# Optional: teacher debug accordion if you kept the teacher JSON earlier
|
| 550 |
# (If you added a teacher debug already, you can leave this out or keep your version.)
|
| 551 |
with gr.Accordion("Teacher debug β Parser & JSON (optional)", open=False):
|
| 552 |
dbg = gr.Textbox(label="LLM/Regex + Raw/Final JSON + Diagnostics", lines=22)
|
| 553 |
|
| 554 |
def _ask_with_hud(user_text, hud):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
# ---- Parse (LLM first, then regex) ----
|
| 556 |
raw_llm = llm_parse(user_text)
|
| 557 |
if raw_llm:
|
|
@@ -596,69 +685,154 @@ with gr.Blocks(css="footer {visibility: hidden}") as demo:
|
|
| 596 |
rate = new_hud.get("rate")
|
| 597 |
if rate is not None:
|
| 598 |
rate = float(rate)
|
| 599 |
-
if rate > 1.0: rate = rate / 100.0
|
| 600 |
else:
|
| 601 |
rate = 0.08
|
| 602 |
|
| 603 |
-
# ----
|
| 604 |
if not which:
|
| 605 |
msg = "Jerry β Tell me which cost (e.g., fuel, repair, depreciation). Check the HUD to see what I have so far."
|
| 606 |
teacher_dbg = _pp({"mode": mode, "raw_llm": raw_llm, "raw_regex": raw_regex, "final_data": new_hud})
|
| 607 |
-
return msg, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud
|
| 608 |
|
|
|
|
| 609 |
missing = missing_for(which, new_hud)
|
| 610 |
if missing:
|
| 611 |
msg = f"Jerry β Not enough data for {which}. Missing: {', '.join(missing)}. Check the HUD and add what's missing."
|
| 612 |
teacher_dbg = _pp({"mode": mode, "raw_llm": raw_llm, "raw_regex": raw_regex, "final_data": new_hud, "missing": missing})
|
| 613 |
-
return msg, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud
|
| 614 |
-
|
| 615 |
-
# ----
|
| 616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 617 |
if which == "repair_per_acre_year":
|
| 618 |
r = compute_repair_per_acre_year(equip, cost, life, acres, speed)
|
| 619 |
ans = f"Jerry β REPAIR per acre-year: fraction={r['fraction']:.3f}, value=${r['repair_per_acre_year']:.2f}/ac/yr (mode={mode})"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 620 |
elif which == "fuel_per_acre":
|
| 621 |
f = compute_fuel_per_acre(hp, diesel, speed)
|
| 622 |
ans = f"Jerry β FUEL per acre=${f:.2f} (mode={mode})"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 623 |
elif which == "lube_per_acre":
|
| 624 |
f = compute_fuel_per_acre(hp, diesel, speed)
|
| 625 |
l = compute_lube_per_acre(f)
|
| 626 |
ans = f"Jerry β LUBE per acre=${l:.2f} (mode={mode})"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 627 |
elif which == "labor_per_acre":
|
| 628 |
l = compute_labor_per_acre(wage, speed)
|
| 629 |
ans = f"Jerry β LABOR per acre=${l:.2f} (mode={mode})"
|
| 630 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 631 |
elif which == "depreciation_per_acre_year":
|
| 632 |
d = compute_depr_per_acre_year(cost, salvage, life, acres)
|
| 633 |
-
ans = (
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
|
|
|
|
|
|
| 637 |
elif which == "occ_per_acre_year":
|
| 638 |
o = compute_occ_per_acre_year(cost, salvage, rate, life, acres)
|
| 639 |
-
ans = (
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
|
|
|
|
|
|
| 643 |
elif which == "tax":
|
| 644 |
-
|
| 645 |
-
ans = f"Jerry β TAX per acre=${
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 646 |
elif which == "insurance":
|
| 647 |
-
|
| 648 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 649 |
elif which == "housing":
|
| 650 |
-
|
| 651 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
teacher_dbg = _pp({
|
| 653 |
"mode": mode,
|
| 654 |
"raw_llm": raw_llm,
|
| 655 |
"raw_regex": raw_regex,
|
| 656 |
"final_data": new_hud
|
| 657 |
})
|
| 658 |
-
return ans, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud
|
| 659 |
-
|
|
|
|
| 660 |
# Wire it up; we update 5 outputs: student answer, HUD JSON, changed fields, teacher debug, and the state
|
| 661 |
-
ask.click(_ask_with_hud, [q, hud_state], [out, hud_box, changed_box, dbg, hud_state])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 662 |
|
| 663 |
if __name__=="__main__":
|
| 664 |
demo.queue().launch(server_name="0.0.0.0",server_port=int(os.getenv("PORT","7860")))
|
|
|
|
| 250 |
# Housing = 0.5% of cost, allocated per acre
|
| 251 |
return 0.005 * float(cost) / max(float(acres), 1e-9)
|
| 252 |
|
| 253 |
+
# Blackbord helpers
|
| 254 |
+
# ---------- Blackboard helpers ----------
|
| 255 |
+
def _fmt_money(x):
|
| 256 |
+
return f"${x:,.2f}"
|
| 257 |
+
|
| 258 |
+
def _fmt_pct(x):
|
| 259 |
+
return f"{x*100:.1f}%"
|
| 260 |
+
|
| 261 |
+
def explain_repair(equip, cost, life, acres, speed, frac, hours, per_ac_yr):
|
| 262 |
+
# Iowa method: AccumHours = life * (acres / speed) and Repair$/ac/yr = (Cost Γ AccumRepairFraction) / (life Γ acres)
|
| 263 |
+
# Sources: Repair method & per-year/per-acre basis in course notes.
|
| 264 |
+
src = "Iowa table (Accumulated Repair Fraction) β see class notes."
|
| 265 |
+
return (
|
| 266 |
+
"REPAIR β show your work\n"
|
| 267 |
+
f"1) Accumulated hours: hours = life Γ (acres / speed) = {life:g} Γ ({acres:g} / {speed:g}) = {hours:,.1f} hr.\n"
|
| 268 |
+
f"2) Table lookup: fraction = {frac:.4f} ({_fmt_pct(frac)}) β {src}\n"
|
| 269 |
+
f"3) Total lifetime repair $: Cost Γ fraction = {_fmt_money(cost)} Γ {frac:.4f} = {_fmt_money(cost*frac)}.\n"
|
| 270 |
+
f"4) Per-acre-per-year: lifetime_repair Γ· (life Γ acres) = {_fmt_money(cost*frac)} Γ· ({life:g} Γ {acres:g}) = {_fmt_money(per_ac_yr)} per ac/yr."
|
| 271 |
+
)
|
| 272 |
+
|
| 273 |
+
def explain_fuel(hp, diesel, speed, per_ac):
|
| 274 |
+
# Fuel Cost per ac = (0.044 Γ PTO HP Γ Diesel $/gal) / speed_acph
|
| 275 |
+
# Reference: fuel formula in notes.
|
| 276 |
+
return (
|
| 277 |
+
"FUEL β show your work\n"
|
| 278 |
+
f"Fuel$/ac = (0.044 Γ PTO_HP Γ diesel_price) Γ· speed\n"
|
| 279 |
+
f" = (0.044 Γ {hp:g} Γ {_fmt_money(diesel)}/gal) Γ· {speed:g}\n"
|
| 280 |
+
f" = {_fmt_money(per_ac)} per ac."
|
| 281 |
+
)
|
| 282 |
+
|
| 283 |
+
def explain_lube(fuel_per_ac, lube_per_ac):
|
| 284 |
+
# Lube = 0.15 Γ Fuel (Iowa)
|
| 285 |
+
return (
|
| 286 |
+
"LUBE β show your work\n"
|
| 287 |
+
f"Lube$/ac = 0.15 Γ Fuel$/ac = 0.15 Γ {_fmt_money(fuel_per_ac)} = {_fmt_money(lube_per_ac)} per ac."
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
+
def explain_labor(wage, speed, per_ac):
|
| 291 |
+
# Labor$/ac = wage / speed
|
| 292 |
+
return (
|
| 293 |
+
"LABOR β show your work\n"
|
| 294 |
+
f"Labor$/ac = wage Γ· speed = {_fmt_money(wage)} Γ· {speed:g} = {_fmt_money(per_ac)} per ac."
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
def explain_depr(cost, salvage_frac, salvage, life, acres, per_ac_yr):
|
| 298 |
+
# Dep$/ac/yr = (C β S) / (life Γ acres)
|
| 299 |
+
return (
|
| 300 |
+
"DEPRECIATION β show your work\n"
|
| 301 |
+
f"1) Salvage fraction from table = {salvage_frac:.3f} ({_fmt_pct(salvage_frac)}); Salvage S = {_fmt_money(salvage)}.\n"
|
| 302 |
+
f"2) Dep$/ac/yr = (C β S) Γ· (life Γ acres) = ({_fmt_money(cost)} β {_fmt_money(salvage)}) Γ· ({life:g} Γ {acres:g})\n"
|
| 303 |
+
f" = {_fmt_money(per_ac_yr)} per ac/yr."
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
def explain_occ(cost, salvage, rate, acres, per_ac_yr):
|
| 307 |
+
# OCC$/ac/yr = rate Γ ((C + S)/2) Γ· acres (no division by life)
|
| 308 |
+
avg_inv = 0.5*(cost+salvage)
|
| 309 |
+
return (
|
| 310 |
+
"OPPORTUNITY COST OF CAPITAL β show your work\n"
|
| 311 |
+
f"Avg investment = (C + S)/2 = ({_fmt_money(cost)} + {_fmt_money(salvage)}) / 2 = {_fmt_money(avg_inv)}.\n"
|
| 312 |
+
f"OCC$/ac/yr = rate Γ AvgInvestment Γ· acres = {rate:.3f} Γ {_fmt_money(avg_inv)} Γ· {acres:g}\n"
|
| 313 |
+
f" = {_fmt_money(per_ac_yr)} per ac/yr."
|
| 314 |
+
)
|
| 315 |
+
|
| 316 |
+
def explain_tax_ins_housing(kind, cost, per_ac):
|
| 317 |
+
# Tax=1% of cost; Insurance=0.5%; Housing=0.5% (annual) then Γ· acres for per-acre basis
|
| 318 |
+
rates = {"tax":0.01, "insurance":0.005, "housing":0.005}
|
| 319 |
+
r = rates[kind]
|
| 320 |
+
label = {"tax":"TAX","insurance":"INSURANCE","housing":"HOUSING"}[kind]
|
| 321 |
+
return (
|
| 322 |
+
f"{label} β show your work\n"
|
| 323 |
+
f"{label}$/ac/yr = ({r:.3f} Γ Cost) Γ· acres = ({r:.3f} Γ {_fmt_money(cost)}) Γ· acres = {_fmt_money(per_ac)} per ac/yr."
|
| 324 |
+
)
|
| 325 |
+
|
| 326 |
+
|
| 327 |
|
| 328 |
# ---- Keyword intent + Regex fallback ----
|
| 329 |
NUM=r"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?"
|
|
|
|
| 619 |
gr.Markdown("### Student HUD β what Jerry sees")
|
| 620 |
hud_box = gr.Textbox(label="Final Data (persists this session)", lines=18, value=_pp({k: None for k in HUD_FIELDS}))
|
| 621 |
changed_box = gr.Textbox(label="Fields updated by last prompt", lines=3, value="(none)")
|
| 622 |
+
|
| 623 |
+
# NEW: a Blackboard textbox (under your teacher accordion or right below out)
|
| 624 |
+
#blackboard = gr.Textbox(label="Blackboard β step-by-step", lines=14)
|
| 625 |
+
steps_box = gr.Textbox(label="Blackboard β show the work", lines=16, value="(none)")
|
| 626 |
+
|
| 627 |
# Optional: teacher debug accordion if you kept the teacher JSON earlier
|
| 628 |
# (If you added a teacher debug already, you can leave this out or keep your version.)
|
| 629 |
with gr.Accordion("Teacher debug β Parser & JSON (optional)", open=False):
|
| 630 |
dbg = gr.Textbox(label="LLM/Regex + Raw/Final JSON + Diagnostics", lines=22)
|
| 631 |
|
| 632 |
def _ask_with_hud(user_text, hud):
|
| 633 |
+
"""
|
| 634 |
+
Returns SIX values in this order:
|
| 635 |
+
1) student answer (string)
|
| 636 |
+
2) HUD JSON (string)
|
| 637 |
+
3) changed fields (string)
|
| 638 |
+
4) teacher debug JSON (string)
|
| 639 |
+
5) new HUD state (dict)
|
| 640 |
+
6) blackboard/steps text (string)
|
| 641 |
+
"""
|
| 642 |
+
steps_text = "(none)" # Blackboard default
|
| 643 |
+
|
| 644 |
# ---- Parse (LLM first, then regex) ----
|
| 645 |
raw_llm = llm_parse(user_text)
|
| 646 |
if raw_llm:
|
|
|
|
| 685 |
rate = new_hud.get("rate")
|
| 686 |
if rate is not None:
|
| 687 |
rate = float(rate)
|
| 688 |
+
if rate > 1.0: rate = rate / 100.0
|
| 689 |
else:
|
| 690 |
rate = 0.08
|
| 691 |
|
| 692 |
+
# ---- If no which_cost, early return (SIX outputs) ----
|
| 693 |
if not which:
|
| 694 |
msg = "Jerry β Tell me which cost (e.g., fuel, repair, depreciation). Check the HUD to see what I have so far."
|
| 695 |
teacher_dbg = _pp({"mode": mode, "raw_llm": raw_llm, "raw_regex": raw_regex, "final_data": new_hud})
|
| 696 |
+
return msg, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud, steps_text
|
| 697 |
|
| 698 |
+
# ---- Check readiness for chosen cost; early return if missing (SIX outputs) ----
|
| 699 |
missing = missing_for(which, new_hud)
|
| 700 |
if missing:
|
| 701 |
msg = f"Jerry β Not enough data for {which}. Missing: {', '.join(missing)}. Check the HUD and add what's missing."
|
| 702 |
teacher_dbg = _pp({"mode": mode, "raw_llm": raw_llm, "raw_regex": raw_regex, "final_data": new_hud, "missing": missing})
|
| 703 |
+
return msg, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud, steps_text
|
| 704 |
+
|
| 705 |
+
# ---- Derived diagnostics for Blackboard (safe) ----
|
| 706 |
+
# salvage parts (works whether salvage_parts exists or not)
|
| 707 |
+
def _safe_salvage_parts(equip, cost, hp, acres, speed, life):
|
| 708 |
+
try:
|
| 709 |
+
# try the convenience helper if present in your file
|
| 710 |
+
return salvage_parts(equip, cost, hp, acres, speed, life) # (frac, salvage, class)
|
| 711 |
+
except Exception:
|
| 712 |
+
# fallback to the earlier direct computation
|
| 713 |
+
try:
|
| 714 |
+
machine_class = classify_machine_for_salvage(equip, hp)
|
| 715 |
+
except Exception:
|
| 716 |
+
machine_class = None
|
| 717 |
+
try:
|
| 718 |
+
annual_hours = float(acres)/max(float(speed), 1e-9)
|
| 719 |
+
except Exception:
|
| 720 |
+
annual_hours = 0.0
|
| 721 |
+
try:
|
| 722 |
+
salv_frac = get_salvage_fraction(machine_class, annual_hours, float(life)) if machine_class else None
|
| 723 |
+
except Exception:
|
| 724 |
+
salv_frac = None
|
| 725 |
+
if salv_frac is None:
|
| 726 |
+
salv_frac = 0.20
|
| 727 |
+
return float(salv_frac), float(cost)*float(salv_frac), machine_class or equip
|
| 728 |
+
|
| 729 |
+
salv_frac, salvage, salvage_class = _safe_salvage_parts(equip, cost, hp, acres, speed, life)
|
| 730 |
+
|
| 731 |
+
# ---- Compute chosen cost + Blackboard text ----
|
| 732 |
if which == "repair_per_acre_year":
|
| 733 |
r = compute_repair_per_acre_year(equip, cost, life, acres, speed)
|
| 734 |
ans = f"Jerry β REPAIR per acre-year: fraction={r['fraction']:.3f}, value=${r['repair_per_acre_year']:.2f}/ac/yr (mode={mode})"
|
| 735 |
+
# Blackboard
|
| 736 |
+
try:
|
| 737 |
+
steps_text = explain_repair(
|
| 738 |
+
equip=equip, cost=cost, life=life, acres=acres, speed=speed,
|
| 739 |
+
frac=r["fraction"], hours=r["hours"], per_ac_yr=r["repair_per_acre_year"]
|
| 740 |
+
)
|
| 741 |
+
except Exception:
|
| 742 |
+
steps_text = "(repair: explanation unavailable)"
|
| 743 |
+
|
| 744 |
elif which == "fuel_per_acre":
|
| 745 |
f = compute_fuel_per_acre(hp, diesel, speed)
|
| 746 |
ans = f"Jerry β FUEL per acre=${f:.2f} (mode={mode})"
|
| 747 |
+
try:
|
| 748 |
+
steps_text = explain_fuel(hp=hp, diesel=diesel, speed=speed, per_ac=f)
|
| 749 |
+
except Exception:
|
| 750 |
+
steps_text = "(fuel: explanation unavailable)"
|
| 751 |
+
|
| 752 |
elif which == "lube_per_acre":
|
| 753 |
f = compute_fuel_per_acre(hp, diesel, speed)
|
| 754 |
l = compute_lube_per_acre(f)
|
| 755 |
ans = f"Jerry β LUBE per acre=${l:.2f} (mode={mode})"
|
| 756 |
+
try:
|
| 757 |
+
steps_text = explain_lube(fuel_per_ac=f, lube_per_ac=l)
|
| 758 |
+
except Exception:
|
| 759 |
+
steps_text = "(lube: explanation unavailable)"
|
| 760 |
+
|
| 761 |
elif which == "labor_per_acre":
|
| 762 |
l = compute_labor_per_acre(wage, speed)
|
| 763 |
ans = f"Jerry β LABOR per acre=${l:.2f} (mode={mode})"
|
| 764 |
+
try:
|
| 765 |
+
steps_text = explain_labor(wage=wage, speed=speed, per_ac=l)
|
| 766 |
+
except Exception:
|
| 767 |
+
steps_text = "(labor: explanation unavailable)"
|
| 768 |
+
|
| 769 |
elif which == "depreciation_per_acre_year":
|
| 770 |
d = compute_depr_per_acre_year(cost, salvage, life, acres)
|
| 771 |
+
ans = f"Jerry β DEPRECIATION per acre-year=${d:.2f} (salvage fraction={salv_frac:.2f}, salvage=${salvage:,.0f}; mode={mode})"
|
| 772 |
+
try:
|
| 773 |
+
steps_text = explain_depr(cost=cost, salvage_frac=salv_frac, salvage=salvage, life=life, acres=acres, per_ac_yr=d)
|
| 774 |
+
except Exception:
|
| 775 |
+
steps_text = "(depreciation: explanation unavailable)"
|
| 776 |
+
|
| 777 |
elif which == "occ_per_acre_year":
|
| 778 |
o = compute_occ_per_acre_year(cost, salvage, rate, life, acres)
|
| 779 |
+
ans = f"Jerry β OCC per acre-year=${o:.2f} (salvage fraction={salv_frac:.2f}, salvage=${salvage:,.0f}; mode={mode})"
|
| 780 |
+
try:
|
| 781 |
+
steps_text = explain_occ(cost=cost, salvage=salvage, rate=rate, acres=acres, per_ac_yr=o)
|
| 782 |
+
except Exception:
|
| 783 |
+
steps_text = "(OCC: explanation unavailable)"
|
| 784 |
+
|
| 785 |
elif which == "tax":
|
| 786 |
+
t = compute_tax_per_acre(cost, acres)
|
| 787 |
+
ans = f"Jerry β TAX per acre-year=${t:.2f} (mode={mode})"
|
| 788 |
+
try:
|
| 789 |
+
steps_text = explain_tax_ins_housing("tax", cost, t)
|
| 790 |
+
except Exception:
|
| 791 |
+
steps_text = "(tax: explanation unavailable)"
|
| 792 |
+
|
| 793 |
elif which == "insurance":
|
| 794 |
+
ins = compute_insurance_per_acre(cost, acres)
|
| 795 |
+
ans = f"Jerry β INSURANCE per acre-year=${ins:.2f} (mode={mode})"
|
| 796 |
+
try:
|
| 797 |
+
steps_text = explain_tax_ins_housing("insurance", cost, ins)
|
| 798 |
+
except Exception:
|
| 799 |
+
steps_text = "(insurance: explanation unavailable)"
|
| 800 |
+
|
| 801 |
elif which == "housing":
|
| 802 |
+
h = compute_housing_per_acre(cost, acres)
|
| 803 |
+
ans = f"Jerry β HOUSING per acre-year=${h:.2f} (mode={mode})"
|
| 804 |
+
try:
|
| 805 |
+
steps_text = explain_tax_ins_housing("housing", cost, h)
|
| 806 |
+
except Exception:
|
| 807 |
+
steps_text = "(housing: explanation unavailable)"
|
| 808 |
+
|
| 809 |
+
else:
|
| 810 |
+
ans = f"Jerry β Unknown cost. (mode={mode})"
|
| 811 |
+
steps_text = "(none)"
|
| 812 |
+
|
| 813 |
teacher_dbg = _pp({
|
| 814 |
"mode": mode,
|
| 815 |
"raw_llm": raw_llm,
|
| 816 |
"raw_regex": raw_regex,
|
| 817 |
"final_data": new_hud
|
| 818 |
})
|
| 819 |
+
return ans, _pp(new_hud), ", ".join(changed) or "(none)", teacher_dbg, new_hud, steps_text
|
| 820 |
+
|
| 821 |
+
|
| 822 |
# Wire it up; we update 5 outputs: student answer, HUD JSON, changed fields, teacher debug, and the state
|
| 823 |
+
#ask.click(_ask_with_hud, [q, hud_state], [out, hud_box, changed_box, dbg, hud_state])
|
| 824 |
+
ask.click(
|
| 825 |
+
_ask_with_hud,
|
| 826 |
+
[q, hud_state], # <-- 2 inputs ONLY
|
| 827 |
+
[out, hud_box, changed_box, dbg, hud_state, steps_box] # <-- 6 outputs
|
| 828 |
+
)
|
| 829 |
+
|
| 830 |
+
|
| 831 |
+
# add this after `changed_box` definition
|
| 832 |
+
# --- Blackboard (always on) ---
|
| 833 |
+
|
| 834 |
+
|
| 835 |
+
|
| 836 |
|
| 837 |
if __name__=="__main__":
|
| 838 |
demo.queue().launch(server_name="0.0.0.0",server_port=int(os.getenv("PORT","7860")))
|