Gulzat's picture
Update app.py
0e478be verified
raw
history blame
4.99 kB
import datetime
from typing import List, Dict, Tuple
import pytz
from langchain.tools import tool # or whatever decorator you use
# ────────────────────────────────────────────────────────────────────────────
# 1️⃣ Keep your existing helper (unchanged)
# ────────────────────────────────────────────────────────────────────────────
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""Return the current local time in a given timezone (YYYY-MM-DD HH:MM:SS)."""
try:
tz = pytz.timezone(timezone)
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return local_time
except Exception as e:
return f"Error: {e}"
# ────────────────────────────────────────────────────────────────────────────
# 2️⃣ New tool: find the first 30-minute slot that fits everyone’s workday
# ────────────────────────────────────────────────────────────────────────────
@tool
def find_overlap_slot(
timezones: List[str],
workday_start: int = 9,
workday_end: int = 18,
slot_minutes: int = 30
) -> str:
"""
Find the next common slot for a stand-up.
Args:
timezones: List of IANA tz strings (e.g. ["Europe/Berlin", "Asia/Bishkek"])
workday_start: Local workday start hour (24h clock, default 09)
workday_end: Local workday end hour (default 18)
slot_minutes: Length of slot to find (default 30)
Returns:
Human-readable description of the first viable slot, or error msg.
"""
# 1. Build a list of "free intervals" for each participant
now_utc = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
candidates: List[Tuple[datetime.datetime, datetime.datetime]] = []
for tz_name in timezones:
try:
tz = pytz.timezone(tz_name)
except pytz.UnknownTimeZoneError:
return f"Unknown timezone: {tz_name}"
local_now = now_utc.astimezone(tz)
# Next work-day window
start_local = local_now.replace(hour=workday_start, minute=0, second=0, microsecond=0)
end_local = local_now.replace(hour=workday_end, minute=0, second=0, microsecond=0)
if local_now > end_local:
# Move to tomorrow
start_local += datetime.timedelta(days=1)
end_local += datetime.timedelta(days=1)
elif local_now > start_local:
# Move start forward so we don't schedule in the past
start_local = local_now
# Convert to UTC for overlap maths
candidates.append((
start_local.astimezone(pytz.utc),
end_local.astimezone(pytz.utc)
))
# 2. Intersect all availability windows
slot_start = max(interval[0] for interval in candidates)
slot_end = min(interval[1] for interval in candidates)
if slot_end - slot_start < datetime.timedelta(minutes=slot_minutes):
return "No overlapping work-hour slot found in the next day."
# 3. Return the first slot of the requested length
chosen_start = slot_start
chosen_end = slot_start + datetime.timedelta(minutes=slot_minutes)
# 4. Build a friendly summary
summary_lines = [
f"✅ Proposed stand-up slot ({slot_minutes} min)",
f" • UTC: {chosen_start.strftime('%Y-%m-%d %H:%M')}{chosen_end.strftime('%H:%M')}"
]
for tz_name in timezones:
tz = pytz.timezone(tz_name)
loc_start = chosen_start.astimezone(tz).strftime('%Y-%m-%d %H:%M')
loc_end = chosen_end.astimezone(tz).strftime('%H:%M')
summary_lines.append(f" • {tz_name}: {loc_start}{loc_end}")
return "\n".join(summary_lines)
# ────────────────────────────────────────────────────────────────────────────
# 3️⃣ Example of an empty placeholder tool you can extend later
# ────────────────────────────────────────────────────────────────────────────
@tool
def my_custom_tool(arg1: str, arg2: int) -> str:
"""A template tool you can repurpose for anything."""
return f"Received arg1={arg1}, arg2={arg2}. What magic will you build?"