Fastwhisper / app /schedule_templates.py
Mbonea's picture
Add loop-break daily fields, proof wizard, and high-intensity coach interrupts.
4c23c1f
Raw
History Blame Contribute Delete
6.3 kB
"""Built-in schedule templates: duty, explore, and restore_fun menus.
Escape (porn binge, family courtroom) is NOT explore.
"""
from __future__ import annotations
from typing import Any
# Each template: default_min, kind, intent, utility U, fse_load, default priority.
TEMPLATES: list[dict[str, Any]] = [
{
"id": "earn_one_ship",
"title": "Earn one ship",
"kind": "earn_ship",
"intent": "duty",
"priority": "P1",
"default_min": 45,
"utility": 0.9,
"fse_load": 0.2,
"label": "Work / earn",
},
{
"id": "admin_task",
"title": "Trip / admin task",
"kind": "admin_spain",
"intent": "duty",
"priority": "P0",
"default_min": 30,
"utility": 0.85,
"fse_load": 0.3,
"label": "Trip / admin",
"locked": True,
},
{
"id": "body_room",
"title": "Body or room care",
"kind": "body_care",
"intent": "duty",
"priority": "P2",
"default_min": 20,
"utility": 0.55,
"fse_load": 0.1,
"label": "Body or room",
},
{
"id": "move_out_line",
"title": "Move-out one line",
"kind": "move_out",
"intent": "duty",
"priority": "P1",
"default_min": 15,
"utility": 0.7,
"fse_load": 0.25,
"label": "Move-out step",
},
{
"id": "food_outside",
"title": "Food outside",
"kind": "food_out",
"intent": "duty",
"priority": "P0",
"default_min": 45,
"utility": 0.8,
"fse_load": 0.15,
"label": "Food",
"locked": True,
},
{
"id": "boundary_5m",
"title": "Boundary practice 5m",
"kind": "boundary",
"intent": "duty",
"priority": "P2",
"default_min": 10,
"utility": 0.5,
"fse_load": 0.2,
"label": "Boundary practice",
},
{
"id": "walk_new_route",
"title": "Timed walk new route 20m",
"kind": "explore",
"intent": "explore",
"priority": "P2",
"default_min": 20,
"utility": 0.45,
"fse_load": 0.05,
"label": "Try something new",
"measure": "rate urge/mood after",
},
{
"id": "music_album",
"title": "Music full album + fun rating",
"kind": "restore_fun",
"intent": "restore_fun",
"priority": "P2",
"default_min": 40,
"utility": 0.4,
"fse_load": 0.05,
"label": "Fun recharge",
},
{
"id": "cook_simple",
"title": "Cook simple meal",
"kind": "explore",
"intent": "explore",
"priority": "P2",
"default_min": 35,
"utility": 0.5,
"fse_load": 0.1,
"label": "Try something new",
"money_optional": True,
},
{
"id": "photo_challenge",
"title": "Photo challenge 20 shots",
"kind": "explore",
"intent": "explore",
"priority": "P2",
"default_min": 25,
"utility": 0.45,
"fse_load": 0.05,
"label": "Try something new",
},
{
"id": "spanish_15",
"title": "Spanish 15m light practice",
"kind": "explore",
"intent": "explore",
"priority": "P2",
"default_min": 15,
"utility": 0.55,
"fse_load": 0.1,
"label": "Try something new",
},
{
"id": "cafe_45",
"title": "Cafe 45m + short journal",
"kind": "restore_fun",
"intent": "restore_fun",
"priority": "P2",
"default_min": 45,
"utility": 0.5,
"fse_load": 0.1,
"label": "Fun recharge",
"money_optional": True,
},
{
"id": "stabilize_10",
"title": "Stabilize: walk/move 10m",
"kind": "stabilize",
"intent": "measure",
"priority": "P1",
"default_min": 10,
"utility": 0.6,
"fse_load": 0.0,
"label": "Stabilize / reset",
"measure": "after urge",
},
{
"id": "sleep_wind",
"title": "Sleep wind-down",
"kind": "sleep_window",
"intent": "duty",
"priority": "P0",
"default_min": 45,
"utility": 0.85,
"fse_load": 0.0,
"label": "Sleep wind-down",
"locked": True,
},
{
"id": "fantasy_slot_25",
"title": "Scheduled movie/fantasy (timer)",
"kind": "restore_fun",
"intent": "restore_fun",
"priority": "P2",
"default_min": 25,
"utility": 0.35,
"fse_load": 0.15,
"label": "Fun recharge",
"notes": "Containment slot — timer on; not a lecture. After timer, one proof brick.",
},
]
KIND_LABELS: dict[str, str] = {
"earn_ship": "Work / earn",
"admin_spain": "Trip / admin",
"body_care": "Body or room",
"move_out": "Move-out step",
"food_out": "Food",
"stabilize": "Stabilize / reset",
"explore": "Try something new",
"restore_fun": "Fun recharge",
"boundary": "Boundary practice",
"sleep_window": "Sleep wind-down",
"other": "Other",
}
def list_templates() -> list[dict[str, Any]]:
return list(TEMPLATES)
def template_by_id(template_id: str) -> dict[str, Any] | None:
for row in TEMPLATES:
if row["id"] == template_id:
return dict(row)
return None
# Default clock slots for empty-day seed (P0 locked first).
SEED_SLOTS: list[tuple[str, str, str]] = [
("earn_one_ship", "09:00", "09:45"),
("food_outside", "12:30", "13:15"),
("stabilize_10", "15:00", "15:15"),
("walk_new_route", "16:30", "16:50"),
("sleep_wind", "22:00", "22:45"),
]
def seed_template_ids(*, capacity_hint: float) -> list[str]:
"""Pick starter template ids under capacity (P0 always; cut P2 when low)."""
ids = ["food_outside", "sleep_wind"]
if capacity_hint >= 0.45:
ids.insert(0, "earn_one_ship")
if capacity_hint < 0.55:
ids.append("stabilize_10")
if capacity_hint >= 0.4:
ids.append("walk_new_route")
# Preserve SEED_SLOTS order
order = {tid: i for i, (tid, _, _) in enumerate(SEED_SLOTS)}
return sorted(set(ids), key=lambda t: order.get(t, 99))