-
Notifications
You must be signed in to change notification settings - Fork 36
/
chat.go
172 lines (140 loc) · 7.72 KB
/
chat.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package openaigo
import "encoding/json"
// ChatCompletionRequestBody:
// https://platform.openai.com/docs/guides/chat/chat-completions-beta
// https://platform.openai.com/docs/api-reference/chat
type ChatCompletionRequestBody struct {
// Model: ID of the model to use.
// Currently, only gpt-3.5-turbo and gpt-3.5-turbo-0301 are supported.
Model string `json:"model"`
// Messages: The messages to generate chat completions for, in the chat format.
// https://platform.openai.com/docs/guides/chat/introduction
// Including the conversation history helps when user instructions refer to prior messages.
// In the example above, the user’s final question of “Where was it played?” only makes sense in the context of the prior messages about the World Series of 2020.
// Because the models have no memory of past requests, all relevant information must be supplied via the conversation.
// If a conversation cannot fit within the model’s token limit, it will need to be shortened in some way.
Messages []Message `json:"messages"`
// Temperature: What sampling temperature to use, between 0 and 2.
// Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
// We generally recommend altering this or top_p but not both.
// Defaults to 1.
Temperature float32 `json:"temperature,omitempty"`
// TopP: An alternative to sampling with temperature, called nucleus sampling,
// where the model considers the results of the tokens with top_p probability mass.
// So 0.1 means only the tokens comprising the top 10% probability mass are considered.
// We generally recommend altering this or temperature but not both.
// Defaults to 1.
TopP float32 `json:"top_p,omitempty"`
// N: How many chat completion choices to generate for each input message.
// Defaults to 1.
N int `json:"n,omitempty"`
// Stream: If set, partial message deltas will be sent, like in ChatGPT.
// Tokens will be sent as data-only server-sent events as they become available,
// with the stream terminated by a data: [DONE] message.
Stream bool `json:"stream,omitempty"`
// StreamCallback is a callback funciton to handle stream response.
// If provided, this library automatically set `Stream` `true`.
// This field is added by github.com/otiai10/openaigo only to handle Stream.
// Thus, it is omitted when the client excute HTTP request.
StreamCallback func(res ChatCompletionResponse, done bool, err error) `json:"-"`
// Stop: Up to 4 sequences where the API will stop generating further tokens.
// Defaults to null.
Stop []string `json:"stop,omitempty"`
// MaxTokens: The maximum number of tokens allowed for the generated answer.
// By default, the number of tokens the model can return will be (4096 - prompt tokens).
MaxTokens int `json:"max_tokens,omitempty"`
// PresencePenalty: Number between -2.0 and 2.0.
// Positive values penalize new tokens based on whether they appear in the text so far,
// increasing the model's likelihood to talk about new topics.
// See more information about frequency and presence penalties.
// https://platform.openai.com/docs/api-reference/parameter-details
PresencePenalty float32 `json:"presence_penalty,omitempty"`
// FrequencyPenalty: Number between -2.0 and 2.0.
// Positive values penalize new tokens based on their existing frequency in the text so far,
// decreasing the model's likelihood to repeat the same line verbatim.
// See more information about frequency and presence penalties.
// https://platform.openai.com/docs/api-reference/parameter-details
FrequencyPenalty float32 `json:"frequency_penalty,omitempty"`
// LogitBias: Modify the likelihood of specified tokens appearing in the completion.
// Accepts a json object that maps tokens (specified by their token ID in the tokenizer)
// to an associated bias value from -100 to 100.
// Mathematically, the bias is added to the logits generated by the model prior to sampling.
// The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection;
// values like -100 or 100 should result in a ban or exclusive selection of the relevant token.
LogitBias map[string]int `json:"logit_bias,omitempty"`
// User: A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more.
// https://platform.openai.com/docs/guides/safety-best-practices/end-user-ids
User string `json:"user,omitempty"`
// Functions: A list of functions which GPT is allowed to request to call.
// Functions []Function `json:"functions,omitempty"`
Functions json.Marshaler `json:"functions,omitempty"`
// FunctionCall: You ain't need it. Default is "auto".
FunctionCall string `json:"function_call,omitempty"`
}
type Functions []Function
func (funcs Functions) MarshalJSON() ([]byte, error) {
if len(funcs) == 0 {
return []byte("[]"), nil
}
return json.Marshal([]Function(funcs))
}
type Function struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Parameters Parameters `json:"parameters,omitempty"`
}
type Parameters struct {
Type string `json:"type,omitempty"` // Must be "object"
Properties map[string]map[string]any `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}
// ChatRequest is just an alias of ChatCompletionRequestBody.
type ChatRequest ChatCompletionRequestBody
// Message: An element of messages parameter.
// The main input is the messages parameter. Messages must be an array of message objects,
// where each object has a role (either “system”, “user”, or “assistant”)
// and content (the content of the message).
// Conversations can be as short as 1 message or fill many pages.
// See https://platform.openai.com/docs/api-reference/chat/create#chat/create-messages
type Message struct {
// Role: Either of "system", "user", "assistant".
// Typically, a conversation is formatted with a system message first, followed by alternating user and assistant messages.
// The system message helps set the behavior of the assistant. In the example above, the assistant was instructed with “You are a helpful assistant.”
// The user messages help instruct the assistant. They can be generated by the end users of an application, or set by a developer as an instruction.
// The assistant messages help store prior responses. They can also be written by a developer to help give examples of desired behavior.
Role string `json:"role"`
// Content: A content of the message.
Content string `json:"content"`
// FunctionCall requested by ChatGPT.
// Only appears in a response from ChatGPT in which ChatGPT wants to call a function.
FunctionCall *FunctionCall `json:"function_call,omitempty"`
// Name of the function called, to tell this message is a result of function_call.
// Only appears in a request from us when the previous message is "function_call" requested by ChatGPT.
Name string `json:"name,omitempty"`
}
type FunctionCall struct {
NameRaw string `json:"name,omitempty"`
ArgumentsRaw string `json:"arguments,omitempty"`
// Arguments map[string]any `json:"arguments,omitempty"`
}
func (fc *FunctionCall) Name() string {
return fc.NameRaw
}
func (fc *FunctionCall) Args() map[string]any {
var args map[string]any
json.Unmarshal([]byte(fc.ArgumentsRaw), &args)
return args
}
type ChatCompletionResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Choices []Choice `json:"choices"`
Usage Usage `json:"usage"`
}
type Choice struct {
Index int `json:"index"`
Message Message `json:"message"`
FinishReason string `json:"finish_reason"`
Delta Message `json:"delta"` // Only appears in stream response
}