diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-03-02 08:18:04 -0500 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-03-02 08:18:29 -0500 |
| commit | f9323c9d33ac55d2a4fcd1f6dbee350cc3416c95 (patch) | |
| tree | 2466f1a6366523416017f75a365087df32ffa107 /web | |
| parent | adb5d6a858e40422a323a63e74aa3d3a310587d9 (diff) | |
| download | x-f9323c9d33ac55d2a4fcd1f6dbee350cc3416c95.tar.xz x-f9323c9d33ac55d2a4fcd1f6dbee350cc3416c95.zip | |
web: add new package chatgpt
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'web')
| -rw-r--r-- | web/chatgpt/chatgpt.go | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/web/chatgpt/chatgpt.go b/web/chatgpt/chatgpt.go new file mode 100644 index 0000000..ad1de30 --- /dev/null +++ b/web/chatgpt/chatgpt.go @@ -0,0 +1,90 @@ +// Package chatgpt is a simple binding to the ChatGPT API. +package chatgpt + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + + "within.website/x/web" +) + +type Request struct { + Model string `json:"model"` + Messages []Message `json:"messages"` +} + +type Message struct { + Role string `json:"role"` + Content string `json:"content"` +} + +type Usage struct { + PromptTokens int `json:"prompt_tokens"` + CompletionTokens int `json:"completion_tokens"` + TotalTokens int `json:"total_tokens"` +} + +type Choice struct { + Message Message `json:"message"` + FinishReason string `json:"finish_reason"` + Index int `json:"index"` +} + +type Response struct { + ID string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + Model string `json:"model"` + Usage Usage `json:"usage"` + Choices []Choice `json:"choices"` +} + +type Client struct { + httpCli *http.Client + apiKey string +} + +func NewClient(apiKey string) Client { + return Client{ + httpCli: &http.Client{}, + apiKey: apiKey, + } +} + +func (c Client) Complete(ctx context.Context, r Request) (*Response, error) { + if r.Model == "" { + r.Model = "gpt-3.5-turbo" + } + + data, err := json.Marshal(r) + if err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://api.openai.com/v1/chat/completions", bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("chatgpt: [unexpected] can't make request???: %w", err) + } + + req.Header.Add("Authorization", "Bearer "+c.apiKey) + req.Header.Add("Content-Type", "application/json") + + resp, err := c.httpCli.Do(req) + if err != nil { + return nil, fmt.Errorf("chatgpt: can't reach API: %w", err) + } + + if resp.StatusCode != http.StatusOK { + return nil, web.NewError(http.StatusOK, resp) + } + + var result Response + if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, fmt.Errorf("chatgpt: can't decode result: %w", err) + } + + return &result, nil +} |
