-
Notifications
You must be signed in to change notification settings - Fork 2
/
impl.go
101 lines (88 loc) · 2.89 KB
/
impl.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
97
98
99
100
101
package chatgpt
import (
"context"
"errors"
openai "github.com/sashabaranov/go-openai"
"go.autokitteh.dev/autokitteh/sdk/sdkmodule"
"go.autokitteh.dev/autokitteh/sdk/sdktypes"
)
const (
defaultModel = openai.GPT3Dot5Turbo
defaultRole = openai.ChatMessageRoleUser
)
// https://pkg.go.dev/github.com/sashabaranov/go-openai#Client.CreateChatCompletion
// https://platform.openai.com/docs/api-reference/chat/create
func (i integration) createChatCompletion(ctx context.Context, args []sdktypes.Value, kwargs map[string]sdktypes.Value) (sdktypes.Value, error) {
// Parse the input arguments.
var (
msg string
req openai.ChatCompletionRequest
)
err := sdkmodule.UnpackArgs(args, kwargs,
"model?", &req.Model,
"message?", &msg,
"messages?", &req.Messages,
)
if err != nil {
return sdktypes.InvalidValue, err
}
if msg != "" && len(req.Messages) > 0 {
return sdktypes.InvalidValue, errors.New("cannot specify both 'message' and 'messages'")
}
if req.Model == "" {
req.Model = defaultModel
}
if msg != "" {
req.Messages = append(req.Messages, openai.ChatCompletionMessage{
Role: defaultRole,
Content: msg,
})
}
// Get auth details from secrets manager.
token := sdkmodule.FunctionDataFromContext(ctx)
auth, err := i.secrets.Get(ctx, i.scope, string(token))
if err != nil {
return sdktypes.InvalidValue, err
}
// Invoke the API method.
client := openai.NewClient(auth["apiKey"])
resp, err := client.CreateChatCompletion(ctx, req)
if err != nil {
jsonResp := ChatCompletionResponse{Error: err.Error()}
return sdktypes.WrapValue(jsonResp)
}
// Parse and return the response.
jsonResp := ChatCompletionResponse{
ID: resp.ID,
Object: resp.Object,
Created: resp.Created,
Model: resp.Model,
Usage: resp.Usage,
SystemFingerprint: resp.SystemFingerprint,
}
for _, c := range resp.Choices {
jsonResp.Choices = append(jsonResp.Choices, ChatCompletionChoice{
Index: c.Index,
Message: c.Message,
FinishReason: string(c.FinishReason),
})
}
return sdktypes.WrapValue(jsonResp)
}
// Workaround for a JSON conversion issue in the client library,
// and for passing errors back to the caller.
type ChatCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []ChatCompletionChoice `json:"choices"`
Usage openai.Usage `json:"usage"`
SystemFingerprint string `json:"system_fingerprint"`
Error string `json:"error,omitempty"`
}
type ChatCompletionChoice struct {
Index int `json:"index"`
Message openai.ChatCompletionMessage `json:"message"`
FinishReason string `json:"finish_reason"`
}