支持工具链
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
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())
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package timeagent
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestResolveBuildsCalendarRanges(t *testing.T) {
|
||||
loc := time.FixedZone("CST", 8*60*60)
|
||||
ctx := Resolve(time.Date(2026, 6, 10, 13, 14, 15, 0, loc))
|
||||
if got := FormatSQLRange(ctx.Today); got != "start=2026-06-10 00:00:00, end_exclusive=2026-06-11 00:00:00" {
|
||||
t.Fatalf("today = %s", got)
|
||||
}
|
||||
if got := FormatSQLRange(ctx.ThisMonth); got != "start=2026-06-01 00:00:00, end_exclusive=2026-07-01 00:00:00" {
|
||||
t.Fatalf("this month = %s", got)
|
||||
}
|
||||
if got := FormatSQLRange(ctx.ThisWeek); got != "start=2026-06-08 00:00:00, end_exclusive=2026-06-15 00:00:00" {
|
||||
t.Fatalf("this week = %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildContextIncludesSQLHints(t *testing.T) {
|
||||
ctx := Resolve(time.Date(2026, 6, 10, 13, 14, 15, 0, time.UTC))
|
||||
text := BuildContext(ctx, "需要日期范围")
|
||||
for _, want := range []string{"时间工具结果", "本月", "start=", "end_exclusive=", "半开区间", "需要日期范围"} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("context missing %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user