mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-12 06:13:57 +00:00
85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// DateTimeTool provides precise current date/time with timezone support.
|
|
// Models use this before creating cron jobs or any time-sensitive operation
|
|
// instead of guessing timestamps from the system prompt's date-only field.
|
|
type DateTimeTool struct {
|
|
now func() time.Time
|
|
}
|
|
|
|
func NewDateTimeTool() *DateTimeTool { return &DateTimeTool{now: time.Now} }
|
|
|
|
func (t *DateTimeTool) Name() string { return "datetime" }
|
|
|
|
func (t *DateTimeTool) Description() string {
|
|
return `Get the current date and time. Use this when you need precise timestamps for scheduling (cron jobs), logging, or any time-sensitive operation.
|
|
|
|
Returns current time in both UTC and the requested timezone.
|
|
If no timezone is provided, returns UTC only.
|
|
Calendar fields such as weekday and iso_weekday are computed by the server and are authoritative. Use them verbatim; never infer or recalculate the weekday from a date.`
|
|
}
|
|
|
|
func (t *DateTimeTool) Parameters() map[string]any {
|
|
return map[string]any{
|
|
"type": "object",
|
|
"properties": map[string]any{
|
|
"timezone": map[string]any{
|
|
"type": "string",
|
|
"description": "IANA timezone name (e.g. 'Asia/Ho_Chi_Minh', 'America/New_York'). If omitted, returns UTC only.",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (t *DateTimeTool) Execute(_ context.Context, args map[string]any) *Result {
|
|
now := time.Now()
|
|
if t != nil && t.now != nil {
|
|
now = t.now()
|
|
}
|
|
utc := now.UTC()
|
|
result := map[string]any{
|
|
"utc": utc.Format(time.RFC3339),
|
|
"utc_date": utc.Format(time.DateOnly),
|
|
"utc_time": utc.Format(time.TimeOnly),
|
|
"utc_weekday": utc.Weekday().String(),
|
|
"utc_iso_weekday": isoWeekday(utc),
|
|
"unix_ms": now.UnixMilli(),
|
|
}
|
|
|
|
if tz, ok := args["timezone"].(string); ok && tz != "" {
|
|
loc, err := time.LoadLocation(tz)
|
|
if err != nil {
|
|
return ErrorResult(fmt.Sprintf("invalid timezone '%s': use IANA names like 'Asia/Ho_Chi_Minh', 'America/New_York'", tz))
|
|
}
|
|
local := now.In(loc)
|
|
result["local"] = local.Format(time.RFC3339)
|
|
result["local_date"] = local.Format(time.DateOnly)
|
|
result["local_time"] = local.Format(time.TimeOnly)
|
|
result["weekday"] = local.Weekday().String()
|
|
result["iso_weekday"] = isoWeekday(local)
|
|
result["utc_offset"] = local.Format("Z07:00")
|
|
result["timezone"] = tz
|
|
}
|
|
|
|
data, err := json.MarshalIndent(result, "", " ")
|
|
if err != nil {
|
|
return ErrorResult(fmt.Sprintf("failed to encode datetime result: %v", err))
|
|
}
|
|
return NewResult(string(data))
|
|
}
|
|
|
|
func isoWeekday(value time.Time) int {
|
|
weekday := int(value.Weekday())
|
|
if weekday == 0 {
|
|
return 7
|
|
}
|
|
return weekday
|
|
}
|