Spaces:
Runtime error
Runtime error
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) | |
# ──────────────────────────────────────────────────────────────────────────── | |
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 | |
# ──────────────────────────────────────────────────────────────────────────── | |
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 | |
# ──────────────────────────────────────────────────────────────────────────── | |
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?" | |