97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
import calendar
|
|
from datetime import datetime, timedelta
|
|
from typing import Any, Dict
|
|
|
|
from .base import ToolSpec
|
|
|
|
|
|
def _parse_offset(args: Dict[str, Any], key: str) -> int:
|
|
value = args.get(key)
|
|
if value is None:
|
|
return 0
|
|
try:
|
|
return int(value)
|
|
except (TypeError, ValueError):
|
|
return 0
|
|
|
|
|
|
def _add_months(dt: datetime, months: int) -> datetime:
|
|
if months == 0:
|
|
return dt
|
|
total = dt.year * 12 + (dt.month - 1) + months
|
|
year = total // 12
|
|
month = total % 12 + 1
|
|
last_day = calendar.monthrange(year, month)[1]
|
|
day = min(dt.day, last_day)
|
|
return dt.replace(year=year, month=month, day=day)
|
|
|
|
|
|
async def _time(args: Dict[str, Any]) -> Dict[str, Any]:
|
|
now = datetime.now()
|
|
year_offset = _parse_offset(args, "year")
|
|
month_offset = _parse_offset(args, "month")
|
|
day_offset = _parse_offset(args, "day")
|
|
hour_offset = _parse_offset(args, "hour")
|
|
minute_offset = _parse_offset(args, "minute")
|
|
second_offset = _parse_offset(args, "second")
|
|
|
|
dt = _add_months(now, year_offset * 12 + month_offset)
|
|
dt = dt + timedelta(days=day_offset, hours=hour_offset, minutes=minute_offset, seconds=second_offset)
|
|
|
|
weekday_names = [
|
|
"Monday",
|
|
"Tuesday",
|
|
"Wednesday",
|
|
"Thursday",
|
|
"Friday",
|
|
"Saturday",
|
|
"Sunday",
|
|
]
|
|
weekday = weekday_names[dt.weekday()]
|
|
dt_str = dt.strftime("%Y-%m-%d %H:%M:%S")
|
|
return {
|
|
"ok": True,
|
|
"summary": f"{dt_str} · {weekday}",
|
|
"data": {
|
|
"datetime": dt_str,
|
|
"weekday": weekday,
|
|
"offset": {
|
|
"year": year_offset,
|
|
"month": month_offset,
|
|
"day": day_offset,
|
|
"hour": hour_offset,
|
|
"minute": minute_offset,
|
|
"second": second_offset,
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
TOOLS: Dict[str, ToolSpec] = {
|
|
"time": ToolSpec(
|
|
name="time",
|
|
description=(
|
|
"Use to get the current date, time, or weekday, or resolve relative dates such as tomorrow or last month."
|
|
" Returns server-local time to the second and the weekday in English; omit all arguments for the current time."
|
|
" year/month/day/hour/minute/second are signed offsets from now and can be combined;"
|
|
" day=1 means this time tomorrow and month=-1 means this time last month."
|
|
" Year and month offsets apply first, clamping the day to the target month's last day,"
|
|
" followed by day/hour/minute/second offsets. Does not convert time zones."
|
|
),
|
|
parameters={
|
|
"type": "object",
|
|
"properties": {
|
|
"year": {"type": "integer", "description": "Year offset from now; may be negative. Default: 0."},
|
|
"month": {"type": "integer", "description": "Month offset from now; may be negative. Default: 0."},
|
|
"day": {"type": "integer", "description": "Day offset from now; may be negative. Default: 0."},
|
|
"hour": {"type": "integer", "description": "Hour offset from now; may be negative. Default: 0."},
|
|
"minute": {"type": "integer", "description": "Minute offset from now; may be negative. Default: 0."},
|
|
"second": {"type": "integer", "description": "Second offset from now; may be negative. Default: 0."},
|
|
},
|
|
"additionalProperties": False,
|
|
},
|
|
requires_confirmation=False,
|
|
handler=_time,
|
|
),
|
|
}
|