Parent Effort
{escape(tradeoffs['parent_effort'])}
Interruption Risk
{escape(tradeoffs['interruption_risk'])}
Cleanup
{escape(tradeoffs['cleanup_burden'])}
"""
def format_output(result):
"""Format the JSON result into custom HTML cards for display."""
sa = result.get("situation_assessment", {})
rp = result.get("recommended_plan", {})
ap = result.get("alternative_plan", {})
ef = result.get("emergency_fallback", {})
m = result.get("metrics", {})
timeline_items = []
for item in rp.get("timeline", []):
timeline_items.append(f"""
{escape(str(item.get('time', '')))}
{escape(str(item.get('activity', '')))}
Rationale: {escape(str(item.get('rationale', '')))}
""")
timeline_html = "\n".join(timeline_items) or """
We've got you.
A realistic plan for the next parenting window, built around energy, constraints, and backup options.
{icon_badge("clipboard-list")}
Situation Assessment
Primary Goal
{escape(str(sa.get('primary_goal', 'N/A')))}
Primary Constraint
{escape(str(sa.get('primary_constraint', 'N/A')))}
Secondary Constraints
{escape(str(sa.get('secondary_constraints', 'N/A')))}
{icon_badge("check")}
Recommended Plan
{escape(str(rp.get('title', 'Plan')))} (Effort: {escape(str(rp.get('total_effort', 'N/A')))})
{timeline_html}
{render_tradeoff_chips(recommended_tradeoffs)}
Best when: {escape(recommended_tradeoffs['best_when'])}
{icon_badge("arrow-right-left")}
Alternative Plan
{escape(str(ap.get('title', 'Lower-effort backup path')))}
{alternative_steps_html}
Key difference: {escape(str(ap.get('key_difference', 'This option gives up some enrichment to protect parent bandwidth.')))}
{render_tradeoff_chips(alternative_tradeoffs)}
Best when: {escape(alternative_tradeoffs['best_when'])}
{icon_badge("siren")}
Emergency Fallback
{escape(str(ef.get('title', 'Immediate stabilization plan')))}
Use when: {escape(str(ef.get('trigger', 'The primary plan is no longer working.')))}
{fallback_steps_html}
{render_tradeoff_chips(fallback_tradeoffs)}
Best when: {escape(fallback_tradeoffs['best_when'])}
Tip: Keep one quiet backup option ready before the first transition gets wobbly.
"""
# Gradio UI
with gr.Blocks(
title="Parent Co-Pilot"
) as demo:
gr.HTML(f"""