Nora_Chatbot / app.py
Mephesto1's picture
Upload app.py
5b5af0f verified
Raw
History Blame Contribute Delete
7.44 kB
# %%
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()