-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenAI.go
124 lines (99 loc) · 2.92 KB
/
OpenAI.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package OpenAI
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"github.com/pkoukk/tiktoken-go"
)
// Chat message roles defined by the OpenAI API.
const (
ChatMessageRoleUser = "user"
ChatMessageRoleAssistant = "assistant"
ChatMessageRoleSystem = "system"
ChatMessageRoleFunction = "function"
)
type DataType string
const (
Object DataType = "object"
Number DataType = "number"
Integer DataType = "integer"
String DataType = "string"
Array DataType = "array"
Null DataType = "null"
Boolean DataType = "boolean"
)
// Definition is a struct for describing a JSON Schema.
// It is fairly limited, and you may have better luck using a third-party library.
type Definition struct {
// Type specifies the data type of the schema.
Type DataType `json:"type,omitempty"`
// Description is the description of the schema.
Description string `json:"description,omitempty"`
// Enum is used to restrict a value to a fixed set of values. It must be an array with at least
// one element, where each element is unique. You will probably only use this with strings.
Enum []string `json:"enum,omitempty"`
// Properties describes the properties of an object, if the schema type is Object.
Properties map[string]Definition `json:"properties"`
// Required specifies which properties are required, if the schema type is Object.
Required []string `json:"required,omitempty"`
// Items specifies which data type an array contains, if the schema type is Array.
Items *Definition `json:"items,omitempty"`
}
func (d Definition) MarshalJSON() ([]byte, error) {
if d.Properties == nil {
d.Properties = make(map[string]Definition)
}
type Alias Definition
return json.Marshal(struct {
Alias
}{
Alias: (Alias)(d),
})
}
type OpenAI struct {
ApiKey string
}
func Create(apiKey string) *OpenAI {
return &OpenAI{
ApiKey: apiKey,
}
}
func (openAI *OpenAI) CalculateTokens(request OpenAIChatRequest) (tokens int, err error) {
return CalculateTokens(request)
}
func CalculateTokens(request OpenAIChatRequest) (tokens int, err error) {
tke, err := tiktoken.GetEncoding("cl100k_base")
if err != nil {
err = fmt.Errorf("getEncoding: %v", err)
return
}
for _, message := range request.Messages {
tokens += len(tke.Encode(message.Content, nil, nil))
}
return
}
func (openAI *OpenAI) Chat(request OpenAIChatRequest) (response OpenAIChatResponse, err error) {
// Convert the struct to JSON.
jsonData, err := json.Marshal(request)
if err != nil {
return
}
// Convert the JSON data to a string reader.
payload := strings.NewReader(string(jsonData))
req, _ := http.NewRequest("POST", API_URL, payload)
req.Header.Add("Authorization", "Bearer "+openAI.ApiKey)
req.Header.Add("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return
}
json.Unmarshal(body, &response)
return response, nil
}