File size: 4,990 Bytes
9b5b26a 3a431a1 9b5b26a 3a431a1 9b5b26a 3a431a1 9b5b26a 3a431a1 9b5b26a 3a431a1 9b5b26a 3a431a1 8c01ffb 3a431a1 8c01ffb 3a431a1 ae7a494 3a431a1 ae7a494 3a431a1 8c01ffb 3a431a1 8c01ffb 3a431a1 8c01ffb 3a431a1 8fe992b 3a431a1 9b5b26a 3a431a1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
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?"
|