# %% from agents.sensor_agent import SensorAgent from agents.pod_agent import PodAgent from agents.schedule_agent import ScheduleAgent from datetime import datetime from datetime import datetime, timedelta from typing import List, Dict import gradio as gr # Pod sequence: simple list of strings pod_sequence = ["Pod A", "Pod B", "Pod C", "Pod D", "Pod E", "Pod F", "Pod G", "Pod H", "Pod I"] # Mutable pod history for overrides pod_history = [] # Initialize agents sensor_agent = SensorAgent(change_days=10) pod_agent = PodAgent(sequence=pod_sequence, change_days=3) schedule_agent = ScheduleAgent(sensor_agent, pod_agent) # Generate unified schedule start_date = datetime.strptime("06/18/2025", "%m/%d/%Y") schedule = schedule_agent.generate_schedule(start_date, num_cycles=3) # Sensor rotation sequence: left_arm → left_leg → right_leg → right_arm → repeat def generate_sensor_schedule(start_date: datetime, num_changes: int = 4) -> List[Dict]: sides = ["left_arm", "left_leg", "right_leg", "right_arm"] schedule = [] for i in range(num_changes): schedule.append({ "date": start_date + timedelta(days=i * 10), "site": sides[i % len(sides)], "side": "left" if "left" in sides[i % len(sides)] else "right" }) return schedule def get_sensor_for_date(date: datetime, sensor_schedule: List[Dict]) -> Dict: for i in range(len(sensor_schedule) - 1): start = sensor_schedule[i]["date"] end = sensor_schedule[i + 1]["date"] if start <= date < end: return sensor_schedule[i] return sensor_schedule[-1] test_sensor_schedule = generate_sensor_schedule(start_date) # test_date = start_date + timedelta(days=7) # sensor = get_sensor_for_date(test_date, test_sensor_schedule) # print(f"\nSensor on {test_date.strftime('%m/%d/%Y')}: {sensor}") def get_valid_sites(current_sensor: Dict, next_sensor: Dict) -> List[str]: current_site = current_sensor["site"] current_side = current_sensor["side"] next_side = next_sensor["side"] valid_sites = [] if current_site == "left_arm": valid_sites = ["left_arm", "left_leg", "left_stomach"] if next_side != current_side: valid_sites.append("right_stomach") elif current_site == "right_arm": valid_sites = ["right_arm", "right_leg", "right_stomach"] if next_side != current_side: valid_sites.append("left_stomach") elif current_site == "left_leg": valid_sites = ["left_arm", "left_leg", "left_stomach"] if next_side != current_side: valid_sites.append("right_stomach") elif current_site == "right_leg": valid_sites = ["right_arm", "right_leg", "right_stomach"] return valid_sites def choose_site(valid_sites: List[str], history: List[str]) -> str: # Avoid using the most recent site recent = history[-1] if history else None filtered = [site for site in valid_sites if site != recent] # If all sites were used recently, fall back to any valid site if not filtered: return valid_sites[0] # Prefer sites least recently used for site in filtered: if site not in history[-3:]: # adjustable window return site # If all filtered sites were used recently, pick the first return filtered[0] # Pod Forecast Preview # valid_sites = ['left_arm', 'left_leg', 'left_stomach', 'right_stomach'] # history = ['left_leg', 'right_stomach', 'left_arm'] # chosen = choose_site(valid_sites, history) # print(f"Chosen site: {chosen}") def forecast_schedule( pod_change_dates: List[datetime], sensor_schedule: List[Dict], history: List[str] = pod_history # ← use global history ) -> List[Dict]: forecast = [] for pod_date in pod_change_dates: current_sensor = get_sensor_for_date(pod_date, sensor_schedule) next_sensor = get_sensor_for_date(pod_date + timedelta(days=3), sensor_schedule) valid_sites = get_valid_sites(current_sensor, next_sensor) chosen_site = choose_site(valid_sites, history) forecast.append({ "date": pod_date, "site": chosen_site, "sensor_side": current_sensor["side"], "next_sensor_side": next_sensor["side"], "reason": "Valid for both current and next sensor" }) history.append(chosen_site) return forecast # Simulate pod change dates pod_change_dates = [start_date + timedelta(days=i * 3) for i in range(10)] # Forecast pod placements forecast = forecast_schedule(pod_change_dates, test_sensor_schedule) # Display forecast for entry in forecast: date_str = entry["date"].strftime("%m/%d/%Y") print(f"{date_str} — Pod Site: {entry['site']} (Sensor: {entry['sensor_side']})") # Combine pod forecast and sensor schedule combined_schedule = [] # Add sensor entries for sensor in test_sensor_schedule: combined_schedule.append({ "date": sensor["date"], "type": "Sensor", "site": sensor["site"], "side": sensor["side"] }) # Add pod forecast entries for pod in forecast: combined_schedule.append({ "date": pod["date"], "type": "Pod", "site": pod["site"], "side": pod["sensor_side"] }) # Sort by date combined_schedule.sort(key=lambda x: x["date"]) # Display unified timeline print("\n📅 Unified Schedule:") for entry in combined_schedule: date_str = entry["date"].strftime("%m/%d/%Y") print(f"{date_str} — {entry['type']} ({entry['site']})") def respond_to_query(message: str, history: list) -> str: message = message.lower() if "next pod" in message: next_pod = forecast[0] date = next_pod["date"].strftime("%m/%d/%Y") return f"Your next pod site is {next_pod['site']} on {date}." elif "next sensor" in message: next_sensor = test_sensor_schedule[1] date = next_sensor["date"].strftime("%m/%d/%Y") return f"Your next sensor site is {next_sensor['site']} on {date}." elif "full schedule" in message or "timeline" in message: lines = [] for entry in combined_schedule: date = entry["date"].strftime("%m/%d/%Y") lines.append(f"{date} — {entry['type']} ({entry['site']})") return "\n".join(lines) elif "i used" in message: try: site = message.split("i used")[1].strip().replace(".", "") pod_history.append(site) return f"Thanks, I’ve logged {site} as your most recent pod site." except: return "I couldn’t quite understand the site you used. Try saying something like 'I used right_leg today.'" else: return "I can help with pod and sensor scheduling. Try asking about your next pod or sensor site." emergency_info = """ ### 🚨 Emergency Contacts **Pediatric Endocrinology Emergency Line** 📞 518-262-5723 **Nora’s Doctor** 🏥 ALBANY MED PEDIATRIC ENDOCRINOLOGY 📍 3 Crossings Blvd, Suite Pediatric Endocrinology 📍 Clifton Park, NY 12065-4166 📞 518-264-3600 --- """ from agents.chat_agent import ChatAgent chat_agent = ChatAgent() demo = chat_agent.render() demo.launch()