File size: 4,990 Bytes
9b5b26a 0e478be 9b5b26a 0e478be 9b5b26a 0e478be 9b5b26a 0e478be 9b5b26a 0e478be 9b5b26a 0e478be 8c01ffb 0e478be 8c01ffb 0e478be ae7a494 0e478be ae7a494 0e478be 8c01ffb 0e478be 8c01ffb 0e478be 8c01ffb 0e478be 8fe992b 0e478be 9b5b26a 0e478be |
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?"
|