-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathapp.go
96 lines (78 loc) · 4.23 KB
/
app.go
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
package main
import (
"fmt"
"log/slog"
"strings"
"time"
_ "time/tzdata"
"github.com/yomorun/yomo/serverless"
)
// Description outlines the functionality for the LLM Function Calling feature.
// It provides a detailed description of the function's purpose, essential for
// integration with LLM Function Calling. The presence of this function and its
// return value make the function discoverable and callable within the LLM
// ecosystem. For more information on Function Calling, refer to the OpenAI
// documentation at: https://platform.openai.com/docs/guides/function-calling
func Description() string {
return `if user asks timezone converter related questions, extract the source time and timezone information to "timeString" and "sourceTimezone", extract the target timezone information to "targetTimezone". the desired "timeString" format is "YYYY-MM-DD HH:MM:SS". the "sourceTimezone" and "targetTimezone" are in IANA Time Zone Database identifier format. The function will convert the time from the source timezone to the target timezone and return the converted time as a string in the format "YYYY-MM-DD HH:MM:SS". If you are not sure about the date value of "timeString", you pretend date as today.`
}
// Parameter defines the arguments for the LLM Function Calling.
type Parameter struct {
TimeString string `json:"timeString" jsonschema:"description=The source time string to be converted, the desired format is 'YYYY-MM-DD HH:MM:SS'"`
SourceTimezone string `json:"sourceTimezone" jsonschema:"description=The source timezone of the time string, in IANA Time Zone Database identifier format"`
TargetTimezone string `json:"targetTimezone" jsonschema:"description=The target timezone to convert the timeString to, in IANA Time Zone Database identifier format"`
}
// InputSchema defines the argument structure for LLM Function Calling. It
// utilizes jsonschema tags to detail the definition. For jsonschema in Go,
// see https://github.com/invopop/jsonschema.
func InputSchema() any {
return &Parameter{}
}
const timeFormat = "2006-01-02 15:04:05"
// Handler orchestrates the core processing logic of this function.
// - ctx.ReadLLMArguments() parses LLM Function Calling Arguments.
// - ctx.WriteLLMResult() sends the retrieval result back to LLM.
func Handler(ctx serverless.Context) {
// parse the input data generated by llm tools_call
var msg Parameter
ctx.ReadLLMArguments(&msg)
slog.Info("parse arguments", "source", msg.SourceTimezone, "target", msg.TargetTimezone, "time", msg.TimeString)
if msg.TargetTimezone == "" {
msg.TargetTimezone = "UTC"
}
// should gurantee date will not be "YYYY-MM-DD"
if strings.Contains(msg.TimeString, "YYYY-MM-DD") {
msg.TimeString = strings.ReplaceAll(msg.TimeString, "YYYY-MM-DD", time.Now().Format("2006-01-02"))
}
targetTime, err := ConvertTimezone(msg.TimeString, msg.SourceTimezone, msg.TargetTimezone)
if err != nil {
slog.Error("[sfn] ConvertTimezone error", "err", err)
ctx.WriteLLMResult("can not convert the time right now, please try later")
return
}
ctx.WriteLLMResult(fmt.Sprintf("This time in timezone %s is %s when %s in %s", msg.TargetTimezone, targetTime, msg.TimeString, msg.SourceTimezone))
}
// ConvertTimezone converts the current time from the source timezone to the target timezone.
// It returns the converted time as a string in the format "2006-01-02 15:04:05".
func ConvertTimezone(timeString, sourceTimezone, targetTimezone string) (string, error) {
slog.Info("<ConvertTimezone>", "timeString", timeString, "sourceTimezone", sourceTimezone, "targetTimezone", targetTimezone)
// Get the location of the source timezone
sourceLoc, err := time.LoadLocation(sourceTimezone)
if err != nil {
return "", fmt.Errorf("invalid source timezone: %v", err)
}
// Get the time in the source timezone
sourceTime, err := time.ParseInLocation(timeFormat, timeString, sourceLoc)
if err != nil {
return "", fmt.Errorf("invalid time string: %v", err)
}
// Get the location of the target timezone
targetLoc, err := time.LoadLocation(targetTimezone)
if err != nil {
return "", fmt.Errorf("invalid target timezone: %v", err)
}
// Convert the source time to the target timezone
targetTime := sourceTime.In(targetLoc)
// Return the target time as a string
return targetTime.Format(timeFormat), nil
}