From 5b4e1413ed2020de1f9f6bdf1a39912b70e76f2c Mon Sep 17 00:00:00 2001 From: kardolus Date: Wed, 6 Nov 2024 23:05:12 +0100 Subject: [PATCH] chore: update file paths for resources --- README.md | 2 +- api/README.md | 133 ++++++++++++++++++ cmd/chatgpt/main.go | 8 +- .../chatgpt/resources}/chatgpt-cli.tape | 0 {resources => cmd/chatgpt/resources}/vhs.gif | Bin .../testdata => test/data}/completions.json | 0 {resources/testdata => test/data}/error.json | 0 .../testdata => test/data}/history.json | 0 {resources/testdata => test/data}/models.json | 0 test/integration/integration_test.go | 4 +- test/utils.go | 4 +- 11 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 api/README.md rename {resources => cmd/chatgpt/resources}/chatgpt-cli.tape (100%) rename {resources => cmd/chatgpt/resources}/vhs.gif (100%) rename {resources/testdata => test/data}/completions.json (100%) rename {resources/testdata => test/data}/error.json (100%) rename {resources/testdata => test/data}/history.json (100%) rename {resources/testdata => test/data}/models.json (100%) diff --git a/README.md b/README.md index e1514ab..3b37806 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ChatGPT CLI provides a powerful command-line interface for seamless interaction with ChatGPT models via OpenAI and Azure, featuring streaming capabilities and extensive configuration options. -![a screenshot](resources/vhs.gif) +![a screenshot](cmd/chatgpt/resources/vhs.gif) ## Table of Contents diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..bce42c6 --- /dev/null +++ b/api/README.md @@ -0,0 +1,133 @@ +# API Package Documentation + +This api package provides core types, request/response models, and utilities for interacting with the ChatGPT CLI’s API. It includes data structures for managing completions, messages, and error responses, as well as supporting JSON marshaling behavior. + +## Package Structure +```shell +api +├── client # Client interface for handling API calls +├── completions.go # Structures for completions API requests/responses +├── http # HTTP client for network requests +└── models.go # Data models for ChatGPT API +``` + +## Overview + +The api package contains types and functions to manage communication with the ChatGPT API. Key components include: + +* Data Models: Defines Message, CompletionsRequest, CompletionsResponse, and other structures for API data handling. +* Client and HTTP Layer: The client and http sub-packages implement the API client and HTTP requests, respectively. +* Custom Types: Includes custom JSON marshalers for fine-grained control of the API response structure. + +### Core Data Structures + +#### CompletionsRequest + +The CompletionsRequest struct models the parameters for making a completion request to the API. + +```go +type CompletionsRequest struct { + Model string `json:"model"` + Temperature float64 `json:"temperature"` + TopP float64 `json:"top_p"` + FrequencyPenalty float64 `json:"frequency_penalty,omitempty"` + MaxTokens int `json:"max_tokens"` + PresencePenalty float64 `json:"presence_penalty,omitempty"` + Messages []Message `json:"messages"` + Stream bool `json:"stream"` + Seed int `json:"seed,omitempty"` +} +``` + +* Model: Specifies the model to use. +* Temperature and TopP: Control the response variability. +* Messages: The conversation history to provide context for responses. + +### CompletionsResponse + +The CompletionsResponse struct represents a response from the API. + +```go +type CompletionsResponse 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"` +} +``` + +#### Message + +Represents a message in a conversation, including the role and content. +```go +type Message struct { + Role string `json:"role"` + Content string `json:"content"` +} +``` + +* Role: The role of the message (e.g., user, assistant). +* Content: The actual text content of the message. + +#### Error Handling + +The ErrorResponse struct models errors returned by the API: +```go +type ErrorResponse struct { + Error struct { + Message string `json:"message"` + Type string `json:"type"` + Code string `json:"code"` + } `json:"error"` +} +``` + +Errors include fields for message, type, and code, allowing structured error handling. + +#### Custom JSON Marshalling + +The Float64 type is a custom wrapper around float64 with special JSON marshalling behavior, which omits the field if the value is zero. + +```go +type Float64 float64 + +func (f Float64) MarshalJSON() ([]byte, error) { + if f == 0.0 { + return []byte("null"), nil + } + return json.Marshal(float64(f)) +} +``` + +## HTTP Client (api/http) + +The http package provides a client for making HTTP requests, allowing integration with the ChatGPT API. + +### RestCaller + +The RestCaller struct handles POST and GET requests, manages error responses, and processes streamed responses. + +### Usage + +To make a completion request: +```go +client := api.NewClient(config) +request := api.CompletionsRequest{ + Model: "gpt-3.5-turbo", + Messages: []api.Message{ + { + Role: "user", Content: "Hello, ChatGPT!" + }, + }, + } + +response, err := client.Query(request) +if err != nil { + log.Fatal(err) +} +fmt.Println(response) +``` + +This setup initializes the API client, creates a completion request, and processes the response. \ No newline at end of file diff --git a/cmd/chatgpt/main.go b/cmd/chatgpt/main.go index 29fe30e..d8b922a 100644 --- a/cmd/chatgpt/main.go +++ b/cmd/chatgpt/main.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/kardolus/chatgpt-cli/api/client" "github.com/kardolus/chatgpt-cli/api/http" - utils2 "github.com/kardolus/chatgpt-cli/cmd/chatgpt/utils" + "github.com/kardolus/chatgpt-cli/cmd/chatgpt/utils" "github.com/kardolus/chatgpt-cli/internal" "github.com/spf13/pflag" "gopkg.in/yaml.v3" @@ -230,7 +230,7 @@ func run(cmd *cobra.Command, args []string) error { } if cmd.Flag("prompt").Changed { - prompt, err := utils2.FileToString(promptFile) + prompt, err := utils.FileToString(promptFile) if err != nil { return err } @@ -278,7 +278,7 @@ func run(cmd *cobra.Command, args []string) error { defer rl.Close() commandPrompt := func(counter, usage int) string { - return utils2.FormatPrompt(c.Config.CommandPrompt, counter, usage, time.Now()) + return utils.FormatPrompt(c.Config.CommandPrompt, counter, usage, time.Now()) } qNum, usage := 1, 0 @@ -291,7 +291,7 @@ func run(cmd *cobra.Command, args []string) error { return nil } - fmtOutputPrompt := utils2.FormatPrompt(c.Config.OutputPrompt, qNum, usage, time.Now()) + fmtOutputPrompt := utils.FormatPrompt(c.Config.OutputPrompt, qNum, usage, time.Now()) if queryMode { result, qUsage, err := c.Query(input) diff --git a/resources/chatgpt-cli.tape b/cmd/chatgpt/resources/chatgpt-cli.tape similarity index 100% rename from resources/chatgpt-cli.tape rename to cmd/chatgpt/resources/chatgpt-cli.tape diff --git a/resources/vhs.gif b/cmd/chatgpt/resources/vhs.gif similarity index 100% rename from resources/vhs.gif rename to cmd/chatgpt/resources/vhs.gif diff --git a/resources/testdata/completions.json b/test/data/completions.json similarity index 100% rename from resources/testdata/completions.json rename to test/data/completions.json diff --git a/resources/testdata/error.json b/test/data/error.json similarity index 100% rename from resources/testdata/error.json rename to test/data/error.json diff --git a/resources/testdata/history.json b/test/data/history.json similarity index 100% rename from resources/testdata/history.json rename to test/data/history.json diff --git a/resources/testdata/models.json b/test/data/models.json similarity index 100% rename from resources/testdata/models.json rename to test/data/models.json diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go index 4646adf..6cae60a 100644 --- a/test/integration/integration_test.go +++ b/test/integration/integration_test.go @@ -7,7 +7,7 @@ import ( "github.com/kardolus/chatgpt-cli/config" "github.com/kardolus/chatgpt-cli/history" "github.com/kardolus/chatgpt-cli/internal" - utils2 "github.com/kardolus/chatgpt-cli/test" + "github.com/kardolus/chatgpt-cli/test" "github.com/onsi/gomega/gexec" "github.com/sclevine/spec" "github.com/sclevine/spec/report" @@ -580,7 +580,7 @@ func testIntegration(t *testing.T, when spec.G, it spec.S) { historyFile := path.Join(filePath, "history", "default.json") Expect(historyFile).NotTo(BeAnExistingFile()) - bytes, err := utils2.FileToBytes("history.json") + bytes, err := test.FileToBytes("history.json") Expect(err).NotTo(HaveOccurred()) Expect(os.WriteFile(legacyFile, bytes, 0644)).To(Succeed()) diff --git a/test/utils.go b/test/utils.go index 004db49..9835127 100644 --- a/test/utils.go +++ b/test/utils.go @@ -17,9 +17,9 @@ func FileToBytes(fileName string) ([]byte, error) { err error ) if strings.Contains(thisFile, "vendor") { - urlPath, err = filepath.Abs(path.Join(thisFile, "../../../../../..", "resources", "testdata", fileName)) + urlPath, err = filepath.Abs(path.Join(thisFile, "../../../../../..", "test", "data", fileName)) } else { - urlPath, err = filepath.Abs(path.Join(thisFile, "../..", "resources", "testdata", fileName)) + urlPath, err = filepath.Abs(path.Join(thisFile, "../..", "test", "data", fileName)) } if err != nil {