LifeStack / agent /conflict_generator.py
Soham Banerjee
deploy: pure lifestack with partitioned wisdom pool
77da5ce
import json
import random
from dataclasses import dataclass, field, asdict
@dataclass
class ConflictEvent:
id: str
title: str
story: str
primary_disruption: dict
decisions_required: list[str]
resource_budget: dict
difficulty: int
TEMPLATES = [
# DIFFICULTY 1
ConflictEvent(
id="d1_gym",
title="The Slump",
story="You haven't seen the inside of a gym in ten days. Your energy is flagging and your favorite jeans feel tight.",
primary_disruption={"physical_health.fitness": -15.0},
decisions_required=["Wake up early for a run", "Join a weekend boot camp", "Ignore it and rest"],
resource_budget={"time": 4.0, "money": 0.0, "energy": 20.0},
difficulty=1
),
ConflictEvent(
id="d1_bill",
title="Forgotten Invoice",
story="A late notice arrived for your electricity bill. It's not a lot, but the late fee is annoying.",
primary_disruption={"finances.liquidity": -20.0},
decisions_required=["Pay it now", "Call to dispute the fee", "Set up autopay for next time"],
resource_budget={"time": 1.0, "money": 100.0, "energy": 5.0},
difficulty=1
),
ConflictEvent(
id="d1_argument",
title="Heated Group Chat",
story="A minor political disagreement in the group chat turned personal. Everyone is being quiet now.",
primary_disruption={"relationships.social": -20.0},
decisions_required=["Apologize to the group", "Message the friend privately", "Mute the chat for a week"],
resource_budget={"time": 2.0, "money": 30.0, "energy": 15.0},
difficulty=1
),
# DIFFICULTY 2
ConflictEvent(
id="d2_project",
title="The Surge",
story="Your boss just walked by and dropped a 'small favor' on your desk. It looks like it'll take ten hours.",
primary_disruption={"career.workload": 25.0, "time.free_hours_per_week": -20.0},
decisions_required=["Work late all week", "Delegate parts to a junior", "Refuse the assignment"],
resource_budget={"time": 10.0, "money": 0.0, "energy": 40.0},
difficulty=2
),
ConflictEvent(
id="d2_car",
title="Check Engine Light",
story="Your car started making a rhythmic thumping sound on the highway. The mechanic says the repair isn't cheap.",
primary_disruption={"finances.liquidity": -30.0, "time.commute_burden": 25.0},
decisions_required=["Repair it immediately", "Take the bus for a week", "Borrow a car from a friend"],
resource_budget={"time": 5.0, "money": 500.0, "energy": 10.0},
difficulty=2
),
ConflictEvent(
id="d2_neglect",
title="Cold Dinner",
story="Your partner mentions they feel like 'roommates' lately. You realize you haven't had a real conversation in weeks.",
primary_disruption={"relationships.romantic": -25.0, "mental_wellbeing.stress_level": 20.0},
decisions_required=["Plan a surprise date", "Have a long talk tonight", "Buy a thoughtful gift"],
resource_budget={"time": 6.0, "money": 150.0, "energy": 30.0},
difficulty=2
),
# DIFFICULTY 3
ConflictEvent(
id="d3_interview",
title="The Opportunity",
story="An old contact reached out for a dream job interview. You need to prep while keeping your current job afloat.",
primary_disruption={"career.workload": 20.0, "time.free_hours_per_week": -15.0, "mental_wellbeing.stress_level": 20.0},
decisions_required=["Intensive weekend prep", "Fake a sick day to interview", "Turn it down to stay stable"],
resource_budget={"time": 12.0, "money": 50.0, "energy": 50.0},
difficulty=3
),
ConflictEvent(
id="d3_family",
title="Family SOS",
story="Your sibling is going through a rough patch and needs help moving out and some financial support.",
primary_disruption={"relationships.family": 20.0, "time.free_hours_per_week": -25.0, "finances.liquidity": -20.0},
decisions_required=["Spend the weekend helping", "Send them money but stay home", "Help them find other movers"],
resource_budget={"time": 15.0, "money": 400.0, "energy": 60.0},
difficulty=3
),
ConflictEvent(
id="d3_health",
title="The Warning Sign",
story="You had a fainting spell at the office. Tests are expensive, and doctors say you need immediate change.",
primary_disruption={"physical_health.energy": -30.0, "mental_wellbeing.stress_level": 30.0, "finances.liquidity": -40.0},
decisions_required=["Take a week of medical leave", "Consult a high-end specialist", "Change diet and sleep habits"],
resource_budget={"time": 20.0, "money": 800.0, "energy": 5.0},
difficulty=3
),
# DIFFICULTY 4
ConflictEvent(
id="d4_review",
title="Judgment Day",
story="A major performance review is in three days. Rumors of layoffs are circulating and the atmosphere is tense.",
primary_disruption={"career.workload": 30.0, "mental_wellbeing.stress_level": 25.0, "relationships.romantic": -15.0, "time.free_hours_per_week": -20.0},
decisions_required=["Pull all-nighters to prove worth", "Start networking for new roles", "Draft a defensive report"],
resource_budget={"time": 18.0, "money": 0.0, "energy": 80.0},
difficulty=4
),
ConflictEvent(
id="d4_move",
title="The Big Relocation",
story="You've decided to move across the country for growth. The logistics are a nightmare and friends are sad to see you go.",
primary_disruption={"finances.liquidity": -50.0, "relationships.social": -30.0, "career.growth_trajectory": 20.0, "time.admin_overhead": 30.0},
decisions_required=["Hire full-service movers", "Host a series of farewell dinners", "DIY pack everything"],
resource_budget={"time": 30.0, "money": 1500.0, "energy": 100.0},
difficulty=4
),
ConflictEvent(
id="d4_audit",
title="Tax Audit",
story="The IRS has flagged your last three years of returns. You need to dig through thousands of documents while paying a CPA.",
primary_disruption={"finances.long_term_health": -20.0, "mental_wellbeing.stress_level": 30.0, "time.admin_overhead": 40.0, "finances.liquidity": -15.0},
decisions_required=["Spend nights scanning receipts", "Hire a tax lawyer", "Try to settle immediately"],
resource_budget={"time": 25.0, "money": 1000.0, "energy": 40.0},
difficulty=4
),
# DIFFICULTY 5
ConflictEvent(
id="d5_friday",
title="Friday 6PM",
story="Your flight just got cancelled. Your card declined trying to rebook. Your boss moved Monday deadline to Sunday.",
primary_disruption={"career.workload": 35.0, "finances.liquidity": -40.0, "mental_wellbeing.stress_level": 30.0, "time.free_hours_per_week": -25.0},
decisions_required=["Book a bus and work on it", "Call boss to negotiate", "Crash at a nearby friend's"],
resource_budget={"time": 10.0, "money": 500.0, "energy": 60.0},
difficulty=5
),
ConflictEvent(
id="d5_storm",
title="The Perfect Storm",
story="Your firm lost its biggest client, your partner moved out, and your car got towed—all on the same Tuesday.",
primary_disruption={"career.stability": -30.0, "relationships.romantic": -25.0, "finances.debt_pressure": 35.0, "physical_health.energy": -25.0},
decisions_required=["Find an emergency side hustle", "Beg partner for a second chance", "Take a mental health day"],
resource_budget={"time": 8.0, "money": 200.0, "energy": 20.0},
difficulty=5
),
ConflictEvent(
id="d5_burnout",
title="The Total Collapse",
story="You can't get out of bed. Your body has quit, your motivation is gone, and work emails are piling into the hundreds.",
primary_disruption={"mental_wellbeing.motivation": -40.0, "physical_health.sleep_quality": -30.0, "career.satisfaction": -35.0, "relationships.family": -20.0},
decisions_required=["Request indefinite medical leave", "Disconnect all electronics", "Let it all burn and sleep"],
resource_budget={"time": 40.0, "money": 2000.0, "energy": 0.0},
difficulty=5
),
# ── TRANSPORT SCENARIOS (difficulty 1–5, all modes) ──────────────────
ConflictEvent(
id="d1_flat_tyre",
title="Flat Tyre",
story="Your bike tyre went flat halfway to work. You're going to be late to a team standup.",
primary_disruption={"time.commute_burden": 20.0, "mental_wellbeing.stress_level": 10.0},
decisions_required=["Call a cab", "Lock the bike and walk", "Ask to dial into the standup"],
resource_budget={"time": 2.0, "money": 30.0, "energy": 15.0},
difficulty=1
),
ConflictEvent(
id="d2_train_delay",
title="Train Delay",
story="Your morning train is delayed 90 minutes due to a signal failure. You have a 9 AM client meeting.",
primary_disruption={"time.commute_burden": 30.0, "career.workload": 15.0, "mental_wellbeing.stress_level": 15.0},
decisions_required=["Dial in remotely", "Take a rideshare", "Reschedule the meeting"],
resource_budget={"time": 3.0, "money": 80.0, "energy": 20.0},
difficulty=2
),
ConflictEvent(
id="d3_car_breakdown",
title="Breakdown on the Highway",
story="Your car engine seized on the freeway during rush hour. Tow + rental = $400 minimum.",
primary_disruption={"finances.liquidity": -35.0, "time.commute_burden": 40.0, "mental_wellbeing.stress_level": 20.0},
decisions_required=["Rent a replacement car", "Rideshare all week", "Borrow from a friend"],
resource_budget={"time": 6.0, "money": 500.0, "energy": 30.0},
difficulty=3
),
ConflictEvent(
id="d4_rideshare_surge",
title="Surge Pricing Nightmare",
story="A major event cancelled all transit. Rideshares are 9x surge. You're presenting in 2 hours.",
primary_disruption={"finances.liquidity": -50.0, "mental_wellbeing.stress_level": 30.0, "time.free_hours_per_week": -10.0},
decisions_required=["Pay the surge", "Organise a carpool", "Present remotely"],
resource_budget={"time": 4.0, "money": 200.0, "energy": 40.0},
difficulty=4
),
ConflictEvent(
id="d5_transit_strike",
title="City-Wide Transit Strike",
story="All buses, trains, and rideshares are on indefinite strike. Your car is in the shop.",
primary_disruption={"time.commute_burden": 50.0, "finances.liquidity": -30.0, "career.workload": 20.0, "mental_wellbeing.stress_level": 25.0},
decisions_required=["Negotiate remote work for the week", "Rent an e-bike/scooter", "Crash at a colleague's place"],
resource_budget={"time": 15.0, "money": 400.0, "energy": 50.0},
difficulty=5
),
]
def generate_conflict(difficulty: int = None) -> ConflictEvent:
if difficulty:
pool = [t for t in TEMPLATES if t.difficulty == difficulty]
else:
pool = TEMPLATES
return random.choice(pool)
def escalate_conflict(conflict: ConflictEvent) -> ConflictEvent:
new_disruption = {k: v * 1.4 for k, v in conflict.primary_disruption.items()}
new_budget = {k: v * 0.7 for k, v in conflict.resource_budget.items()}
new_difficulty = min(5, conflict.difficulty + 1)
return ConflictEvent(
id=f"{conflict.id}_escalated",
title=f"ESCALATED: {conflict.title}",
story=f"Current situation just got much worse. {conflict.story}",
primary_disruption=new_disruption,
decisions_required=conflict.decisions_required,
resource_budget=new_budget,
difficulty=new_difficulty
)
def adaptive_escalate(conflict: ConflictEvent, agent_history: list) -> tuple:
"""Decide whether to escalate, ease, or hold based on past performance.
Args:
conflict: Current conflict event.
agent_history: List of (conflict_id, reward) tuples from past episodes.
Returns:
(new_conflict, reason): Updated conflict and a human-readable reason string.
"""
# Group history by conflict id prefix (strip _escalated suffix)
from collections import defaultdict
by_type = defaultdict(list)
for cid, reward in agent_history:
base_id = cid.replace("_escalated", "")
by_type[base_id].append(reward)
base_id = conflict.id.replace("_escalated", "")
past = by_type.get(base_id, [])
if len(past) >= 3:
avg = sum(past) / len(past)
if avg > 0.7:
# Agent is crushing this type — escalate
escalated = escalate_conflict(conflict)
return escalated, f"Agent averaged {avg:.2f} on {base_id} ({len(past)} runs) — escalating"
elif avg < 0.4:
# Agent is struggling — reduce difficulty
new_diff = max(1, conflict.difficulty - 1)
eased = generate_conflict(difficulty=new_diff)
return eased, f"Agent averaged {avg:.2f} on {base_id} ({len(past)} runs) — easing to difficulty {new_diff}"
# Not enough history — no change
return conflict, "insufficient history — holding"
def save_templates():
import os
data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data", "conflicts.json")
with open(data_path, 'w') as f:
json.dump([asdict(t) for t in TEMPLATES], f, indent=4)
print(f"Saved 15 templates to {data_path}")
def main():
save_templates()
print("\n--- GENERATED CONFLICT SAMPLES ---")
for d in range(1, 6):
c = generate_conflict(d)
print(f"\n[DIFFICULTY {d}] {c.title}")
print(f"Story: {c.story}")
print(f"Primary Disruption: {c.primary_disruption}")
print(f"Resource Budget: {c.resource_budget}")
if __name__ == "__main__":
main()
from core.task import Task, Route, ExoEvent, Milestone
class TaskGenerator:
def generate(self, domain: str = None, difficulty: int = None) -> Task:
diff = difficulty or 3
if domain == "transport_crisis":
return self.generate_transport_crisis(diff)
elif domain == "flight_crisis": # kept as explicit sub-type
return self.generate_flight_crisis(diff)
elif domain == "code_merge_crisis":
return self.generate_code_merge_crisis(diff)
elif domain == "career":
return self.generate_career(diff)
elif domain == "finances":
return self.generate_finances(diff)
elif domain == "relationships":
return self.generate_relationships(diff)
elif domain == "physical_health":
return self.generate_physical_health(diff)
elif domain == "mental_wellbeing":
return self.generate_mental_wellbeing(diff)
elif domain == "time":
return self.generate_time(diff)
else:
return self.generate_transport_crisis(diff)
# ── TRANSPORT CRISIS: master dispatcher ──────────────────────────────
def generate_transport_crisis(self, difficulty: int) -> Task:
"""Randomly choose one of 5 real-world transport disruption modes."""
return random.choice([
self.generate_flight_crisis,
self.generate_train_delay,
self.generate_car_breakdown,
self.generate_rideshare_surge,
self.generate_transit_strike,
])(difficulty)
def generate_train_delay(self, difficulty: int) -> Task:
routes = [
Route(id="dial_in", name="Dial In Remotely", description="Join the meeting via video call from the station.", required_action_types=["communicate"], preconditions={}, consequences={"meeting_attended": True}, closes_routes=["rideshare"], milestones_unlocked=["m1"], final_reward=2.0),
Route(id="rideshare", name="Take a Rideshare", description="Pay for a cab/rideshare and make it there in time.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"arrived_on_time": True}, closes_routes=["dial_in"], milestones_unlocked=["m2"], final_reward=2.5),
Route(id="reschedule", name="Reschedule the Meeting", description="Negotiate a new meeting time with all parties.", required_action_types=["communicate"], preconditions={}, consequences={"meeting_rescheduled": True}, closes_routes=[], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="Meeting attended on time remotely.", condition_key="meeting_attended", condition_value=True, reward=1.0),
Milestone(id="m2", description="Made it to the office despite the delay.", condition_key="arrived_on_time", condition_value=True, reward=1.5),
Milestone(id="m3", description="Meeting rescheduled without relationship cost.", condition_key="meeting_rescheduled", condition_value=True, reward=0.8),
]
events = [
ExoEvent(step=2, probability=0.8, id="delay_extended", description="Train delay extended by another 45 minutes.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
ExoEvent(step=4, probability=0.6, id="rideshare_surge", description="Rideshares now showing 3x surge pricing.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
]
return Task(
id="train_delay_task", domain="transport_crisis", goal="Navigate Train Delay Crisis",
constraints={"budget_max": 150, "deadline_step": 8},
hidden_state={"platform_reassigned": False},
mutable_world={"time.commute_burden": 30.0, "mental_wellbeing.stress_level": 15.0},
visible_world={"time.commute_burden": 30.0, "mental_wellbeing.stress_level": 15.0},
success_conditions=[{"key": "meeting_attended", "value": True}, {"key": "arrived_on_time", "value": True}, {"key": "meeting_rescheduled", "value": True}],
failure_conditions=[{"key": "finances.liquidity", "value": 10.0, "op": "lt"}],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=12 + difficulty * 2, difficulty=difficulty,
domain_metadata={"story": "Signal failure has brought the entire line to a halt.", "transport_mode": "train"}
)
def generate_car_breakdown(self, difficulty: int) -> Task:
routes = [
Route(id="rent_car", name="Rent a Replacement Car", description="Call a rental agency and get mobile again.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"mobile": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=2.5),
Route(id="rideshare_week", name="Rideshare for the Week", description="Use rideshares until the car is repaired.", required_action_types=["spend"], preconditions={}, consequences={"transport_sorted": True}, closes_routes=["rent_car"], milestones_unlocked=["m2"], final_reward=1.5),
Route(id="borrow_car", name="Borrow a Friend's Car", description="Call around and borrow a vehicle.", required_action_types=["communicate"], preconditions={}, consequences={"borrowed": True}, closes_routes=[], milestones_unlocked=["m3"], final_reward=2.0),
]
milestones = [
Milestone(id="m1", description="Replacement vehicle secured.", condition_key="mobile", condition_value=True, reward=1.5),
Milestone(id="m2", description="Transport plan for the week sorted.", condition_key="transport_sorted", condition_value=True, reward=1.0),
Milestone(id="m3", description="Vehicle borrowed without relationship cost.", condition_key="borrowed", condition_value=True, reward=1.2),
]
events = [
ExoEvent(step=2, probability=1.0, id="repair_estimate", description="Mechanic confirms repair takes 3–5 days, not 1.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
ExoEvent(step=5, probability=0.7, id="rental_shortage", description="Rental agencies report no compact cars available.", world_mutation={}, hidden_state_mutation={}, closes_routes=["rent_car"]),
]
return Task(
id="car_breakdown_task", domain="transport_crisis", goal="Recover from Car Breakdown",
constraints={"budget_max": 500, "deadline_step": 10},
hidden_state={"tow_dispatched": False},
mutable_world={"finances.liquidity": -35.0, "time.commute_burden": 40.0},
visible_world={"finances.liquidity": -35.0, "time.commute_burden": 40.0},
success_conditions=[{"key": "mobile", "value": True}, {"key": "transport_sorted", "value": True}, {"key": "borrowed", "value": True}],
failure_conditions=[{"key": "finances.liquidity", "value": 0.0, "op": "le"}],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=14 + difficulty * 2, difficulty=difficulty,
domain_metadata={"story": "Engine seized on the highway. Car is in the shop for days.", "transport_mode": "car"}
)
def generate_rideshare_surge(self, difficulty: int) -> Task:
routes = [
Route(id="pay_surge", name="Pay the Surge Price", description="Absorb the cost and get there on time.", required_action_types=["spend"], preconditions={}, consequences={"arrived": True}, closes_routes=["remote"], milestones_unlocked=["m1"], final_reward=2.0),
Route(id="carpool", name="Organise a Carpool", description="Find colleagues or strangers going the same way.", required_action_types=["communicate", "negotiate"], preconditions={}, consequences={"carpooled": True}, closes_routes=[], milestones_unlocked=["m2"], final_reward=3.0),
Route(id="remote", name="Present Remotely", description="Negotiate to dial in instead of attending in person.", required_action_types=["communicate"], preconditions={}, consequences={"remote_approved": True}, closes_routes=["pay_surge"], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="Arrived at venue on time.", condition_key="arrived", condition_value=True, reward=1.5),
Milestone(id="m2", description="Carpool arranged — zero cost.", condition_key="carpooled", condition_value=True, reward=2.0),
Milestone(id="m3", description="Remote attendance approved.", condition_key="remote_approved", condition_value=True, reward=1.0),
]
events = [
ExoEvent(step=1, probability=1.0, id="surge_spike", description="Surge jumped to 12x. All buses cancelled.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
ExoEvent(step=3, probability=0.9, id="meeting_reminder", description="Organiser sends a 30-minute warning.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
]
return Task(
id="rideshare_surge_task", domain="transport_crisis", goal="Get to the Presentation on Time",
constraints={"budget_max": 200, "deadline_step": 6},
hidden_state={},
mutable_world={"finances.liquidity": -50.0, "mental_wellbeing.stress_level": 30.0},
visible_world={"finances.liquidity": -50.0, "mental_wellbeing.stress_level": 30.0},
success_conditions=[{"key": "arrived", "value": True}, {"key": "carpooled", "value": True}, {"key": "remote_approved", "value": True}],
failure_conditions=[],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=8 + difficulty * 2, difficulty=difficulty,
domain_metadata={"story": "A major city event caused city-wide rideshare surge on your big presentation day.", "transport_mode": "rideshare"}
)
def generate_transit_strike(self, difficulty: int) -> Task:
routes = [
Route(id="wfh_negotiate", name="Negotiate Full Remote Week", description="Get manager approval to WFH for the strike duration.", required_action_types=["communicate", "negotiate"], preconditions={}, consequences={"wfh_approved": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=3.0),
Route(id="micromobility", name="Rent E-Bike / Scooter", description="Use micro-mobility for the week.", required_action_types=["spend"], preconditions={}, consequences={"transport_secured": True}, closes_routes=[], milestones_unlocked=["m2"], final_reward=2.0),
Route(id="colleague_crash",name="Crash at a Colleague's Place", description="Stay near the office temporarily.", required_action_types=["communicate"], preconditions={}, consequences={"accommodation_sorted": True}, closes_routes=[], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="WFH approved for the strike period.", condition_key="wfh_approved", condition_value=True, reward=2.0),
Milestone(id="m2", description="Micro-mobility solution in place.", condition_key="transport_secured", condition_value=True, reward=1.0),
Milestone(id="m3", description="Temporary accommodation sorted.", condition_key="accommodation_sorted",condition_value=True, reward=0.8),
]
events = [
ExoEvent(step=2, probability=0.9, id="strike_extended", description="Union announces the strike could last 2 weeks.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
ExoEvent(step=5, probability=0.7, id="scooter_shortage", description="E-bike rental companies sold out in your area.", world_mutation={}, hidden_state_mutation={}, closes_routes=["micromobility"]),
]
return Task(
id="transit_strike_task", domain="transport_crisis", goal="Survive City-Wide Transit Strike",
constraints={"budget_max": 400, "deadline_step": 14},
hidden_state={},
mutable_world={"time.commute_burden": 50.0, "mental_wellbeing.stress_level": 25.0},
visible_world={"time.commute_burden": 50.0, "mental_wellbeing.stress_level": 25.0},
success_conditions=[{"key": "wfh_approved", "value": True}, {"key": "transport_secured", "value": True}, {"key": "accommodation_sorted", "value": True}],
failure_conditions=[],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=18 + difficulty * 2, difficulty=difficulty,
domain_metadata={"story": "All public transport workers walked off the job. The city is gridlocked.", "transport_mode": "transit_strike"}
)
def generate_flight_crisis(self, difficulty: int) -> Task:
routes = [
Route(id="rebook_premium", name="Rebook Premium Option", description="Call agent and rebook on premium ticket", required_action_types=["communicate", "spend"], preconditions={}, consequences={"flight_rebooked": True}, closes_routes=["wait_lounge"], milestones_unlocked=["m1"], final_reward=2.5),
Route(id="wait_lounge", name="Accept Delay & Work", description="Stay at airport lounge and work on laptop", required_action_types=["rest", "delegate"], preconditions={}, consequences={"caught_up": True}, closes_routes=["rebook_premium"], milestones_unlocked=["m2"], final_reward=1.8),
]
milestones = [
Milestone(id="m1", description="Successfully rebooked flight before deadline", condition_key="flight_rebooked", condition_value=True, reward=1.0),
Milestone(id="m2", description="Caught up with all emergency slack messages", condition_key="caught_up", condition_value=True, reward=0.8),
]
events = [
ExoEvent(step=2, probability=1.0, id="price_surge", description="Ticket prices sharply increased by $300.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
ExoEvent(step=4, probability=1.0, id="lounge_full", description="The airport lounge is now at maximum capacity.", world_mutation={}, hidden_state_mutation={}, closes_routes=["wait_lounge"]),
]
return Task(
id="flight_crisis_task", domain="flight_crisis", goal="Survive Airport Cancellation",
constraints={"budget_max": 800, "deadline_step": 10},
hidden_state={"lounge_capacity": 100},
mutable_world={"mental_wellbeing.stress_level": 25.0, "time.free_hours_per_week": -10.0},
visible_world={"mental_wellbeing.stress_level": 25.0, "time.free_hours_per_week": -10.0},
success_conditions=[{"key": "flight_rebooked", "value": True}, {"key": "caught_up", "value": True}],
failure_conditions=[],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "A major storm grounded commercial flights."}
)
def generate_code_merge_crisis(self, difficulty: int) -> Task:
routes = [
Route(id="revert_commit", name="Revert Commit", description="Quickly revert the broken merge to unblock the team.", required_action_types=["delegate", "communicate"], preconditions={}, consequences={"pipeline_unblocked": True}, closes_routes=["hotfix"], milestones_unlocked=["unblocked"], final_reward=1.5),
Route(id="hotfix", name="Patch Forward", description="Find the logic error and push a hotfix.", required_action_types=["communicate", "spend"], preconditions={}, consequences={"bug_resolved": True}, closes_routes=["revert_commit"], milestones_unlocked=["fixed"], final_reward=3.0),
]
milestones = [
Milestone(id="unblocked", description="CI pipeline is green again", condition_key="pipeline_unblocked", condition_value=True, reward=1.0),
Milestone(id="fixed", description="Bug resolved without losing features", condition_key="bug_resolved", condition_value=True, reward=2.0),
]
events = [
ExoEvent(step=3, probability=0.8, id="cto_ping", description="CTO asks for an ETA on the fix.", world_mutation={}, hidden_state_mutation={}, closes_routes=[]),
]
return Task(
id="code_merge_task", domain="code_merge_crisis", goal="Resolve Production Outage",
constraints={"budget_max": 1000, "deadline_step": 8},
hidden_state={},
mutable_world={"career.stability": -20.0, "mental_wellbeing.stress_level": 30.0},
visible_world={"career.stability": -20.0, "mental_wellbeing.stress_level": 30.0},
success_conditions=[{"key": "pipeline_unblocked", "value": True}, {"key": "bug_resolved", "value": True}],
failure_conditions=[],
event_schedule=events, viable_routes=routes, milestones=milestones,
horizon=10 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "A botched merge just took down the staging environment."}
)
def generate_career(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Negotiate Workload", description="Discuss with manager to reduce workload.", required_action_types=["communicate"], preconditions={}, consequences={"workload_reduced": True}, closes_routes=["r2"], milestones_unlocked=["m1"], final_reward=2.0),
Route(id="r2", name="Find New Job", description="Start applying for new roles.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"job_found": True}, closes_routes=["r1", "r3"], milestones_unlocked=["m2"], final_reward=3.0),
Route(id="r3", name="Delegate to Team", description="Push tasks to junior colleagues.", required_action_types=["delegate"], preconditions={}, consequences={"team_delegated": True}, closes_routes=["r2"], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="Manager agreed to reduce tasks.", condition_key="workload_reduced", condition_value=True, reward=1.0),
Milestone(id="m2", description="Interview secured.", condition_key="job_found", condition_value=True, reward=1.5),
Milestone(id="m3", description="Tasks successfully delegated.", condition_key="team_delegated", condition_value=True, reward=0.8),
]
events = [
ExoEvent(step=3, probability=0.7, id="boss_asks", description="Boss asks for progress on current tasks.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="career_crisis", domain="career", goal="Manage Career Overload", constraints={"budget_max": 500, "deadline_step": 12},
hidden_state={},
mutable_world={"career.workload": 30.0, "time.free_hours_per_week": -20.0},
visible_world={"career.workload": 30.0, "time.free_hours_per_week": -20.0},
success_conditions=[{"key": "workload_reduced", "value": True}, {"key": "job_found", "value": True}, {"key": "team_delegated", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "Severe workload is threatening your career stability."}
)
def generate_finances(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Emergency Fund", description="Dip into savings.", required_action_types=["spend"], preconditions={}, consequences={"used_emergency": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=1.0),
Route(id="r2", name="Negotiate Payment Plan", description="Call the creditor to delay payments.", required_action_types=["communicate"], preconditions={}, consequences={"payment_plan": True}, closes_routes=["r1"], milestones_unlocked=["m2"], final_reward=2.5),
Route(id="r3", name="Sell Asset", description="Liquidate an asset for quick cash.", required_action_types=["communicate", "spend"], preconditions={}, consequences={"asset_sold": True}, closes_routes=["r2"], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="Emergency fund accessed.", condition_key="used_emergency", condition_value=True, reward=0.5),
Milestone(id="m2", description="Favorable payment plan negotiated.", condition_key="payment_plan", condition_value=True, reward=1.0),
Milestone(id="m3", description="Asset successfully sold.", condition_key="asset_sold", condition_value=True, reward=0.8),
]
events = [
ExoEvent(step=2, probability=0.9, id="late_fee", description="A late fee was applied to the balance.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="finance_crisis", domain="finances", goal="Resolve Financial Pressure", constraints={"budget_max": 1000, "deadline_step": 10},
hidden_state={},
mutable_world={"finances.liquidity": -40.0, "finances.debt_pressure": 20.0},
visible_world={"finances.liquidity": -40.0, "finances.debt_pressure": 20.0},
success_conditions=[{"key": "used_emergency", "value": True}, {"key": "payment_plan", "value": True}, {"key": "asset_sold", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "An unexpected expense has caused financial strain."}
)
def generate_relationships(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Couples Therapy", description="Book a session with a therapist.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"therapy_scheduled": True}, closes_routes=["r3"], milestones_unlocked=["m1"], final_reward=3.0),
Route(id="r2", name="Honest Conversation", description="Sit down and talk through issues.", required_action_types=["communicate"], preconditions={}, consequences={"had_conversation": True}, closes_routes=[], milestones_unlocked=["m2"], final_reward=2.0),
Route(id="r3", name="Give Space", description="Take some time apart.", required_action_types=["rest"], preconditions={}, consequences={"giving_space": True}, closes_routes=["r1", "r2"], milestones_unlocked=["m3"], final_reward=1.0),
]
milestones = [
Milestone(id="m1", description="Therapy session completed.", condition_key="therapy_scheduled", condition_value=True, reward=1.5),
Milestone(id="m2", description="A productive conversation occurred.", condition_key="had_conversation", condition_value=True, reward=1.0),
Milestone(id="m3", description="Space given without escalation.", condition_key="giving_space", condition_value=True, reward=0.5),
]
events = [
ExoEvent(step=4, probability=0.6, id="partner_escalates", description="Partner sends an emotional text msg.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="relationship_crisis", domain="relationships", goal="Repair Relationship Friction", constraints={"budget_max": 800, "deadline_step": 14},
hidden_state={},
mutable_world={"relationships.romantic": -30.0, "mental_wellbeing.stress_level": 20.0},
visible_world={"relationships.romantic": -30.0, "mental_wellbeing.stress_level": 20.0},
success_conditions=[{"key": "therapy_scheduled", "value": True}, {"key": "had_conversation", "value": True}, {"key": "giving_space", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "Growing distance and recent conflicts demand attention."}
)
def generate_physical_health(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Medical Leave", description="Request time off to recover.", required_action_types=["communicate", "rest"], preconditions={}, consequences={"on_leave": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=2.5),
Route(id="r2", name="See Specialist", description="Pay for a top-tier medical consultation.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"saw_doctor": True}, closes_routes=[], milestones_unlocked=["m2"], final_reward=2.0),
Route(id="r3", name="Lifestyle Change", description="Commit to better diet and sleep.", required_action_types=["rest"], preconditions={}, consequences={"lifestyle_changed": True}, closes_routes=["r1"], milestones_unlocked=["m3"], final_reward=1.5),
]
milestones = [
Milestone(id="m1", description="Leave approved.", condition_key="on_leave", condition_value=True, reward=1.0),
Milestone(id="m2", description="Clear diagnosis received.", condition_key="saw_doctor", condition_value=True, reward=1.0),
Milestone(id="m3", description="First week of new habits complete.", condition_key="lifestyle_changed", condition_value=True, reward=0.5),
]
events = [
ExoEvent(step=3, probability=0.8, id="doctor_call", description="The clinic calls with test results.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="health_crisis", domain="physical_health", goal="Address Health Warning", constraints={"budget_max": 1500, "deadline_step": 15},
hidden_state={},
mutable_world={"physical_health.energy": -30.0, "mental_wellbeing.stress_level": 30.0},
visible_world={"physical_health.energy": -30.0, "mental_wellbeing.stress_level": 30.0},
success_conditions=[{"key": "on_leave", "value": True}, {"key": "saw_doctor", "value": True}, {"key": "lifestyle_changed", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "Physical symptoms are becoming impossible to ignore."}
)
def generate_mental_wellbeing(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Professional Therapy", description="Start regular therapy sessions.", required_action_types=["spend", "communicate"], preconditions={}, consequences={"therapy_started": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=3.0),
Route(id="r2", name="Disconnect", description="Take a full digital detox break.", required_action_types=["rest"], preconditions={}, consequences={"disconnected": True}, closes_routes=["r3"], milestones_unlocked=["m2"], final_reward=1.5),
Route(id="r3", name="Medication Evaluation", description="See a psychiatrist for options.", required_action_types=["spend"], preconditions={}, consequences={"medication_taken": True}, closes_routes=["r2"], milestones_unlocked=["m3"], final_reward=2.0),
]
milestones = [
Milestone(id="m1", description="Meaningful breakthrough in therapy.", condition_key="therapy_started", condition_value=True, reward=1.5),
Milestone(id="m2", description="Successfully unplugged for 48 hours.", condition_key="disconnected", condition_value=True, reward=0.8),
Milestone(id="m3", description="Prescription acquired.", condition_key="medication_taken", condition_value=True, reward=1.0),
]
events = [
ExoEvent(step=2, probability=0.5, id="panic_attack", description="A sudden wave of severe anxiety hits.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="mental_crisis", domain="mental_wellbeing", goal="Avert Total Burnout", constraints={"budget_max": 600, "deadline_step": 12},
hidden_state={},
mutable_world={"mental_wellbeing.motivation": -35.0, "mental_wellbeing.stress_level": 40.0},
visible_world={"mental_wellbeing.motivation": -35.0, "mental_wellbeing.stress_level": 40.0},
success_conditions=[{"key": "therapy_started", "value": True}, {"key": "disconnected", "value": True}, {"key": "medication_taken", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "Complete exhaustion and loss of motivation."}
)
def generate_time(self, difficulty: int) -> Task:
routes = [
Route(id="r1", name="Reprioritize", description="Restructure calendar and say 'no'.", required_action_types=["communicate"], preconditions={}, consequences={"priorities_reset": True}, closes_routes=[], milestones_unlocked=["m1"], final_reward=2.0),
Route(id="r2", name="Delegate", description="Pay someone or ask for help with chores.", required_action_types=["spend", "delegate"], preconditions={}, consequences={"tasks_delegated": True}, closes_routes=[], milestones_unlocked=["m2"], final_reward=1.5),
Route(id="r3", name="Cancel Commitments", description="Drop out of major upcoming events.", required_action_types=["communicate"], preconditions={}, consequences={"commitments_cancelled": True}, closes_routes=["r1"], milestones_unlocked=["m3"], final_reward=1.0),
]
milestones = [
Milestone(id="m1", description="Calendar cleared of non-essentials.", condition_key="priorities_reset", condition_value=True, reward=1.0),
Milestone(id="m2", description="Help secured for daily tasks.", condition_key="tasks_delegated", condition_value=True, reward=0.8),
Milestone(id="m3", description="Social obligations cancelled.", condition_key="commitments_cancelled", condition_value=True, reward=0.5),
]
events = [
ExoEvent(step=3, probability=0.9, id="new_request", description="A friend asks for an 'urgent' favor.", world_mutation={}, hidden_state_mutation={}, closes_routes=[])
]
return Task(
id="time_crisis", domain="time", goal="Regain Time Control", constraints={"budget_max": 300, "deadline_step": 10},
hidden_state={},
mutable_world={"time.free_hours_per_week": -25.0, "time.admin_overhead": 20.0},
visible_world={"time.free_hours_per_week": -25.0, "time.admin_overhead": 20.0},
success_conditions=[{"key": "priorities_reset", "value": True}, {"key": "tasks_delegated", "value": True}, {"key": "commitments_cancelled", "value": True}],
failure_conditions=[], event_schedule=events, viable_routes=routes, milestones=milestones, horizon=15 + difficulty * 2, difficulty=difficulty, domain_metadata={"story": "You are double-booked and drowning in obligations."}
)