| | import datetime |
| | from typing import List, Dict, Tuple |
| |
|
| | import pytz |
| | from langchain.tools import tool |
| |
|
| | |
| | |
| | |
| | @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}" |
| |
|
| | |
| | |
| | |
| | @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. |
| | """ |
| | |
| | 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) |
| | |
| | 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: |
| | |
| | start_local += datetime.timedelta(days=1) |
| | end_local += datetime.timedelta(days=1) |
| | elif local_now > start_local: |
| | |
| | start_local = local_now |
| |
|
| | |
| | candidates.append(( |
| | start_local.astimezone(pytz.utc), |
| | end_local.astimezone(pytz.utc) |
| | )) |
| |
|
| | |
| | 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." |
| |
|
| | |
| | chosen_start = slot_start |
| | chosen_end = slot_start + datetime.timedelta(minutes=slot_minutes) |
| |
|
| | |
| | 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) |
| |
|
| | |
| | |
| | |
| | @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?" |
| |
|