Add context window

This commit is contained in:
kardolus
2024-03-20 20:41:37 -04:00
parent 9422fa87ad
commit 7908a31119
6 changed files with 27 additions and 14 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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() {

View File

@@ -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,

View File

@@ -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())
}

View File

@@ -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"`