mirror of
https://github.com/kardolus/chatgpt-cli.git
synced 2024-09-08 23:15:00 +03:00
Add context window
This commit is contained in:
10
README.md
10
README.md
@@ -23,8 +23,8 @@ Azure, featuring streaming capabilities and extensive configuration options.
|
||||
- [General Configuration](#general-configuration)
|
||||
- [Azure Configuration](#azure-configuration)
|
||||
- [Command-Line Autocompletion](#command-line-autocompletion)
|
||||
- [Enabling Autocompletion](#enabling-autocompletion)
|
||||
- [Persistent Autocompletion](#persistent-autocompletion)
|
||||
- [Enabling Autocompletion](#enabling-autocompletion)
|
||||
- [Persistent Autocompletion](#persistent-autocompletion)
|
||||
- [Development](#development)
|
||||
- [Reporting Issues and Contributing](#reporting-issues-and-contributing)
|
||||
- [Uninstallation](#uninstallation)
|
||||
@@ -180,6 +180,7 @@ Configuration variables:
|
||||
| `api_key` | Your OpenAI API key. | (none for security) |
|
||||
| `model` | The GPT model used by the application. | 'gpt-3.5-turbo' |
|
||||
| `max_tokens` | The maximum number of tokens that can be used in a single API call. | 4096 |
|
||||
| `context_window` | The memory limit for how much of the conversation can be remembered at one time. | 8192 |
|
||||
| `role` | The system role | 'You are a helpful assistant.' |
|
||||
| `temperature` | What sampling temperature to use, between 0 and 2. Higher values make the output more random; lower values make it more focused and deterministic. | 1.0 |
|
||||
| `frequency_penalty` | Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far. | 0.0 |
|
||||
@@ -201,10 +202,10 @@ the `model` and `max_tokens` parameters, your file might look like this:
|
||||
|
||||
```yaml
|
||||
model: gpt-3.5-turbo-16k
|
||||
max_tokens: 8192
|
||||
max_tokens: 4096
|
||||
```
|
||||
|
||||
This alters the `model` to `gpt-3.5-turbo-16k` and adjusts `max_tokens` to `8192`. All other options, such as `url`
|
||||
This alters the `model` to `gpt-3.5-turbo-16k` and adjusts `max_tokens` to `4096`. All other options, such as `url`
|
||||
, `completions_path`, and `models_path`, can similarly be modified. If the user configuration file cannot be accessed or
|
||||
is missing, the application will resort to the default configuration.
|
||||
|
||||
@@ -248,6 +249,7 @@ name: azure
|
||||
api_key: <your_key>
|
||||
model: <not relevant, read from the completions path>
|
||||
max_tokens: 4096
|
||||
context_window: 8192
|
||||
role: You are a helpful assistant.
|
||||
temperature: 1
|
||||
top_p: 1
|
||||
|
||||
@@ -49,8 +49,8 @@ func New(callerFactory http.CallerFactory, cs config.ConfigStore, hs history.His
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) WithCapacity(capacity int) *Client {
|
||||
c.Config.MaxTokens = capacity
|
||||
func (c *Client) WithContextWindow(window int) *Client {
|
||||
c.Config.ContextWindow = window
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ func (c *Client) processResponse(raw []byte, v interface{}) error {
|
||||
|
||||
func (c *Client) truncateHistory() {
|
||||
tokens, rolling := countTokens(c.History)
|
||||
effectiveTokenSize := calculateEffectiveTokenSize(c.Config.MaxTokens, MaxTokenBufferPercentage)
|
||||
effectiveTokenSize := calculateEffectiveContextWindow(c.Config.ContextWindow, MaxTokenBufferPercentage)
|
||||
|
||||
if tokens <= effectiveTokenSize {
|
||||
return
|
||||
@@ -258,10 +258,10 @@ func (c *Client) updateHistory(response string) {
|
||||
}
|
||||
}
|
||||
|
||||
func calculateEffectiveTokenSize(maxTokenSize int, bufferPercentage int) int {
|
||||
func calculateEffectiveContextWindow(window int, bufferPercentage int) int {
|
||||
adjustedPercentage := 100 - bufferPercentage
|
||||
effectiveTokenSize := (maxTokenSize * adjustedPercentage) / 100
|
||||
return effectiveTokenSize
|
||||
effectiveContextWindow := (window * adjustedPercentage) / 100
|
||||
return effectiveContextWindow
|
||||
}
|
||||
|
||||
func countTokens(messages []types.Message) (int, []int) {
|
||||
|
||||
@@ -23,7 +23,8 @@ import (
|
||||
//go:generate mockgen -destination=configmocks_test.go -package=client_test github.com/kardolus/chatgpt-cli/config ConfigStore
|
||||
|
||||
const (
|
||||
defaultMaxTokens = 50
|
||||
defaultMaxTokens = 100
|
||||
defaultContextWindow = 50
|
||||
defaultURL = "https://default.openai.com"
|
||||
defaultName = "default-name"
|
||||
defaultModel = "gpt-3.5-turbo"
|
||||
@@ -542,7 +543,7 @@ func (f *clientFactory) buildClientWithoutConfig() *client.Client {
|
||||
c, err := client.New(mockCallerFactory, f.mockConfigStore, f.mockHistoryStore)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
return c
|
||||
return c.WithContextWindow(defaultContextWindow)
|
||||
}
|
||||
|
||||
func (f *clientFactory) buildClientWithConfig(config types.Config) *client.Client {
|
||||
@@ -552,7 +553,7 @@ func (f *clientFactory) buildClientWithConfig(config types.Config) *client.Clien
|
||||
c, err := client.New(mockCallerFactory, f.mockConfigStore, f.mockHistoryStore)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
return c
|
||||
return c.WithContextWindow(defaultContextWindow)
|
||||
}
|
||||
|
||||
func (f *clientFactory) withoutHistory() {
|
||||
|
||||
@@ -12,6 +12,7 @@ const (
|
||||
openAIName = "openai"
|
||||
openAIModel = "gpt-3.5-turbo"
|
||||
openAIModelMaxTokens = 4096
|
||||
openAIContextWindow = 8192
|
||||
openAIURL = "https://api.openai.com"
|
||||
openAICompletionsPath = "/v1/chat/completions"
|
||||
openAIModelsPath = "/v1/models"
|
||||
@@ -85,6 +86,7 @@ func (f *FileIO) ReadDefaults() types.Config {
|
||||
Model: openAIModel,
|
||||
Role: openAIRole,
|
||||
MaxTokens: openAIModelMaxTokens,
|
||||
ContextWindow: openAIContextWindow,
|
||||
URL: openAIURL,
|
||||
CompletionsPath: openAICompletionsPath,
|
||||
ModelsPath: openAIModelsPath,
|
||||
|
||||
@@ -24,6 +24,7 @@ func TestUnitConfigManager(t *testing.T) {
|
||||
func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
const (
|
||||
defaultMaxTokens = 10
|
||||
defaultContextWindow = 20
|
||||
defaultName = "default-name"
|
||||
defaultURL = "default-url"
|
||||
defaultModel = "default-model"
|
||||
@@ -58,6 +59,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
APIKey: defaultApiKey,
|
||||
Model: defaultModel,
|
||||
MaxTokens: defaultMaxTokens,
|
||||
ContextWindow: defaultContextWindow,
|
||||
URL: defaultURL,
|
||||
CompletionsPath: defaultCompletionsPath,
|
||||
ModelsPath: defaultModelsPath,
|
||||
@@ -88,6 +90,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
subject := configmanager.New(mockConfigStore).WithEnvironment()
|
||||
|
||||
Expect(subject.Config.MaxTokens).To(Equal(defaultMaxTokens))
|
||||
Expect(subject.Config.ContextWindow).To(Equal(defaultContextWindow))
|
||||
Expect(subject.Config.Name).To(Equal(defaultName))
|
||||
Expect(subject.Config.Model).To(Equal(defaultModel))
|
||||
Expect(subject.Config.URL).To(Equal(defaultURL))
|
||||
@@ -108,6 +111,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
userConfig := types.Config{
|
||||
Model: "user-model",
|
||||
MaxTokens: 20,
|
||||
ContextWindow: 30,
|
||||
URL: "user-url",
|
||||
CompletionsPath: "user-completions-path",
|
||||
ModelsPath: "user-models-path",
|
||||
@@ -129,6 +133,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
|
||||
Expect(subject.Config.Model).To(Equal("user-model"))
|
||||
Expect(subject.Config.MaxTokens).To(Equal(20))
|
||||
Expect(subject.Config.ContextWindow).To(Equal(30))
|
||||
Expect(subject.Config.URL).To(Equal("user-url"))
|
||||
Expect(subject.Config.CompletionsPath).To(Equal("user-completions-path"))
|
||||
Expect(subject.Config.ModelsPath).To(Equal("user-models-path"))
|
||||
@@ -147,6 +152,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
os.Setenv(envPrefix+"API_KEY", "env-api-key")
|
||||
os.Setenv(envPrefix+"MODEL", "env-model")
|
||||
os.Setenv(envPrefix+"MAX_TOKENS", "15")
|
||||
os.Setenv(envPrefix+"CONTEXT_WINDOW", "25")
|
||||
os.Setenv(envPrefix+"URL", "env-url")
|
||||
os.Setenv(envPrefix+"COMPLETIONS_PATH", "env-completions-path")
|
||||
os.Setenv(envPrefix+"MODELS_PATH", "env-models-path")
|
||||
@@ -168,6 +174,7 @@ func testConfig(t *testing.T, when spec.G, it spec.S) {
|
||||
Expect(subject.Config.APIKey).To(Equal("env-api-key"))
|
||||
Expect(subject.Config.Model).To(Equal("env-model"))
|
||||
Expect(subject.Config.MaxTokens).To(Equal(15))
|
||||
Expect(subject.Config.ContextWindow).To(Equal(25))
|
||||
Expect(subject.Config.URL).To(Equal("env-url"))
|
||||
Expect(subject.Config.CompletionsPath).To(Equal("env-completions-path"))
|
||||
Expect(subject.Config.ModelsPath).To(Equal("env-models-path"))
|
||||
@@ -327,7 +334,7 @@ func setValue(config *types.Config, fieldName string, value interface{}) {
|
||||
}
|
||||
|
||||
func unsetEnvironmentVariables(envPrefix string) {
|
||||
variables := []string{"API_KEY", "MODEL", "MAX_TOKENS", "URL", "COMPLETIONS_PATH", "MODELS_PATH", "AUTH_HEADER", "AUTH_TOKEN_PREFIX", "OMIT_HISTORY", "ROLE", "THREAD", "TEMPERATURE", "TOP_P", "FREQUENCY_PENALTY", "PRESENCE_PENALTY"}
|
||||
variables := []string{"API_KEY", "MODEL", "MAX_TOKENS", "CONTEXT_WINDOW", "URL", "COMPLETIONS_PATH", "MODELS_PATH", "AUTH_HEADER", "AUTH_TOKEN_PREFIX", "OMIT_HISTORY", "ROLE", "THREAD", "TEMPERATURE", "TOP_P", "FREQUENCY_PENALTY", "PRESENCE_PENALTY"}
|
||||
for _, variable := range variables {
|
||||
Expect(os.Unsetenv(envPrefix + variable)).To(Succeed())
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ type Config struct {
|
||||
APIKey string `yaml:"api_key"`
|
||||
Model string `yaml:"model"`
|
||||
MaxTokens int `yaml:"max_tokens"`
|
||||
ContextWindow int `yaml:"context_window"`
|
||||
Role string `yaml:"role"`
|
||||
Temperature float64 `yaml:"temperature"`
|
||||
TopP float64 `yaml:"top_p"`
|
||||
|
||||
Reference in New Issue
Block a user