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?"