Spaces:
Build error
Build error
| # %% | |
| 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() | |