package timeagent import ( "fmt" "strings" "time" ) const ActivationPrompt = "提供当前日期、时间和常用时间范围。当用户问题包含今天、明天、昨天、本周、本月、本年、最近、日程安排等相对时间表达时,应先调用此工具;如果后续还需要查数据库,可继续调用 sql。" type Range struct { Start time.Time End time.Time } type Context struct { Now time.Time Today Range Tomorrow Range Yesterday Range ThisWeek Range ThisMonth Range ThisYear Range } func Resolve(now time.Time) Context { loc := now.Location() today := Range{Start: startOfDay(now), End: startOfDay(now).AddDate(0, 0, 1)} tomorrowStart := today.End tomorrow := Range{Start: tomorrowStart, End: tomorrowStart.AddDate(0, 0, 1)} yesterdayEnd := today.Start yesterday := Range{Start: yesterdayEnd.AddDate(0, 0, -1), End: yesterdayEnd} weekdayOffset := (int(now.Weekday()) + 6) % 7 weekStart := today.Start.AddDate(0, 0, -weekdayOffset) monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc) yearStart := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, loc) return Context{ Now: now, Today: today, Tomorrow: tomorrow, Yesterday: yesterday, ThisWeek: Range{Start: weekStart, End: weekStart.AddDate(0, 0, 7)}, ThisMonth: Range{Start: monthStart, End: monthStart.AddDate(0, 1, 0)}, ThisYear: Range{Start: yearStart, End: yearStart.AddDate(1, 0, 0)}, } } func BuildContext(ctx Context, routeReason string) string { var b strings.Builder b.WriteString("时间工具结果。后续工具必须优先使用这里的绝对日期解释用户问题中的相对时间,不要自行猜测当前日期。\n") fmt.Fprintf(&b, "当前本地日期时间:%s\n", ctx.Now.Format("2006-01-02 15:04:05 MST")) fmt.Fprintf(&b, "今天:%s\n", FormatSQLRange(ctx.Today)) fmt.Fprintf(&b, "明天:%s\n", FormatSQLRange(ctx.Tomorrow)) fmt.Fprintf(&b, "昨天:%s\n", FormatSQLRange(ctx.Yesterday)) fmt.Fprintf(&b, "本周:%s\n", FormatSQLRange(ctx.ThisWeek)) fmt.Fprintf(&b, "本月:%s\n", FormatSQLRange(ctx.ThisMonth)) fmt.Fprintf(&b, "本年:%s\n", FormatSQLRange(ctx.ThisYear)) b.WriteString("SQL 日期过滤建议:对日程/事件类表使用半开区间,例如 event_time >= start AND event_time < end;如果实际字段名不同,必须使用 schema 中存在的时间字段。\n") if strings.TrimSpace(routeReason) != "" { b.WriteString("激活原因:" + strings.TrimSpace(routeReason) + "\n") } return b.String() } func FormatDate(t time.Time) string { return t.Format("2006-01-02") } func FormatSQLRange(r Range) string { return fmt.Sprintf("start=%s, end_exclusive=%s", r.Start.Format("2006-01-02 15:04:05"), r.End.Format("2006-01-02 15:04:05")) } func startOfDay(t time.Time) time.Time { y, m, d := t.Date() return time.Date(y, m, d, 0, 0, 0, 0, t.Location()) }