Compare commits

...

10 Commits

Author SHA1 Message Date
d0eb4b7468 extend context size and write to an output file 2025-02-02 02:26:59 -07:00
b926215e94 update to latest gpt model 2025-02-01 22:57:23 -07:00
91da21defb add some other useful prompts 2024-03-20 12:15:35 -06:00
d7598e7c90 fix retries->wait times 2024-03-17 00:07:39 -06:00
917c00c23a make the chat work 2024-03-08 01:13:27 -07:00
1ed6023a14 add basic chat loop 2024-02-25 20:17:48 -07:00
d102e52dfc add comment on how to do retrieval 2023-12-22 12:32:23 -07:00
9810ffdeb8 add single prompt call 2023-12-21 16:53:31 -07:00
02583c7e0e add meilisearch 2023-12-02 12:02:17 -07:00
0ff90a313f add readme 2023-11-05 00:56:02 -06:00
17 changed files with 592 additions and 44 deletions

3
.gitignore vendored
View File

@ -2,3 +2,6 @@ cache/
context.db context.db
context.db-shm context.db-shm
context.db-wal context.db-wal
data.ms
/output.txt
/ctxGPT.exe

2
.idea/dataSources.xml generated
View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="context" uuid="0ca49717-2151-402a-b9b6-d8177360de1a"> <data-source source="LOCAL" name="context" uuid="0ca49717-2151-402a-b9b6-d8177360de1a">
<driver-ref>sqlite.xerial</driver-ref> <driver-ref>deb3aec9-bcff-4dad-9d3a-a86d8508caa5</driver-ref>
<synchronize>true</synchronize> <synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver> <jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:C:\Users\gomas\src\ctxGPT\context.db</jdbc-url> <jdbc-url>jdbc:sqlite:C:\Users\gomas\src\ctxGPT\context.db</jdbc-url>

145
LLMMapper/llmMapper.go Normal file
View File

@ -0,0 +1,145 @@
package LLMMapper
import (
"context"
"encoding/json"
"fmt"
"github.com/pkoukk/tiktoken-go"
"github.com/sashabaranov/go-openai"
"os"
"strings"
"time"
)
const encodingName = "gpt-4"
// const model = openai.GPT4Turbo
const model = "o3-mini"
// const model = openai.GPT4TurboPreview
const maxTokens = 100000
//const maxTokens = 4096
// const maxTokens = 128000
const temperature = 0.7
func GetTokenCount(input string) (int, error) {
tke, err := tiktoken.EncodingForModel(encodingName) // cached in "TIKTOKEN_CACHE_DIR"
if err != nil {
return 0, fmt.Errorf("error getting encoding: %w", err)
}
token := tke.Encode(input, nil, nil)
return len(token), nil
}
// SinglePromptInteraction calls openai chat endpoint with just a system prompt and a user prompt and returns the response
func SinglePromptInteraction(systemPrompt, prompt string) (openai.ChatCompletionResponse, error) {
return singlePromptInteraction(systemPrompt, prompt, 5)
}
// singlePromptInteraction calls openai chat endpoint with just a system prompt and a user prompt and returns the response
// it also attempts 5 retries spaced 5 seconds apart in the case of rate limiting errors
func singlePromptInteraction(systemPrompt, prompt string, retries int) (openai.ChatCompletionResponse, error) {
client := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: systemPrompt,
},
{
Role: openai.ChatMessageRoleUser,
Content: prompt,
},
}
previousTokenCount, err := GetPreviousTokenUsage(messages)
if err != nil {
return openai.ChatCompletionResponse{}, fmt.Errorf("error getting previous token usage: %w", err)
}
messageTokenSize := maxTokens - previousTokenCount
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: model, // switch to the configured Model
Messages: messages,
MaxCompletionTokens: messageTokenSize, // might want to think about how to reduce this
//Temperature: temperature,
},
)
if err != nil {
// if 429, wait and try again
if strings.Contains(err.Error(), "429") && retries > 0 {
seconds := (1 / float64(retries)) * 60 // back off for each retry e.g. 12, 15, 20, 30, 60
fmt.Printf("429 error, waiting %v seconds...\n", seconds)
time.Sleep(time.Duration(seconds) * time.Second)
return singlePromptInteraction(systemPrompt, prompt, retries-1)
}
return openai.ChatCompletionResponse{}, fmt.Errorf("ChatCompletion request error: %w", err)
}
return resp, nil
}
func GetPreviousTokenUsage(messages []openai.ChatCompletionMessage) (int, error) {
messagesRaw, err := json.Marshal(messages)
if err != nil {
return 0, fmt.Errorf("error marshalling messages: %w", err)
}
length, err := GetTokenCount(string(messagesRaw))
if err != nil {
return 0, fmt.Errorf("error getting token count: %w", err)
}
//fmt.Printf("Token Count: %v\n", length)
return length, nil
}
// SendPrompt calls openai chat endpoint with a list of messages and returns the response
func SendPrompt(messages []openai.ChatCompletionMessage) (openai.ChatCompletionResponse, error) {
return sendPrompt(messages, 5)
}
func sendPrompt(messages []openai.ChatCompletionMessage, retries int) (openai.ChatCompletionResponse, error) {
config := openai.DefaultConfig(os.Getenv("OPENAI_API_KEY"))
if os.Getenv("OPENAI_BASE_URL") != "" {
config.BaseURL = os.Getenv("OPENAI_BASE_URL")
}
client := openai.NewClientWithConfig(config)
previousTokenCount, err := GetPreviousTokenUsage(messages)
if err != nil {
return openai.ChatCompletionResponse{}, fmt.Errorf("error getting previous token usage: %w", err)
}
messageTokenSize := maxTokens - previousTokenCount
fmt.Println("messageTokenSize: ", messageTokenSize)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: model, // switch to the configured Model
Messages: messages,
MaxCompletionTokens: messageTokenSize,
//Temperature: temperature,
},
)
if err != nil {
// if 429, wait and try again
if strings.Contains(err.Error(), "429") && retries > 0 {
seconds := (1 / float64(retries)) * 60 // back off for each retry e.g. 12, 15, 20, 30, 60
fmt.Printf("429 error, waiting %v seconds...\n", seconds)
time.Sleep(time.Duration(seconds) * time.Second)
return sendPrompt(messages, retries-1)
}
return openai.ChatCompletionResponse{}, fmt.Errorf("ChatCompletion request error: %w", err)
}
return resp, nil
}

View File

@ -0,0 +1,16 @@
package LLMMapper
import (
"fmt"
"testing"
)
func Test_retryMath(t *testing.T) {
retries := 5
for retries > 0 {
seconds := (1 / float64(retries)) * 60
fmt.Println(seconds, retries)
retries = retries - 1
}
}

146
cmd/chat/chat.go Normal file
View File

@ -0,0 +1,146 @@
package main
import (
"bufio"
"ctxGPT/LLMMapper"
"ctxGPT/promptBuilder"
"encoding/json"
"fmt"
"github.com/sashabaranov/go-openai"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("Go CLI Chat App")
fmt.Println("---------------------")
systemPrompt := ""
//systemPrompt := "You are Mixtral, a locally hosted AI assistant."
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: systemPrompt,
},
}
for {
fmt.Print("You: ")
text, _ := reader.ReadString('\n')
text = strings.TrimSpace(text) // Remove leading and trailing whitespace
// Check if the user wants to exit.
if text == "exit" {
fmt.Println("Exiting chat...")
break
}
messages = append(messages, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleUser,
Content: text,
})
resp, err := LLMMapper.SendPrompt(messages)
if err != nil {
fmt.Println(err)
}
if len(resp.Choices) == 0 {
fmt.Println("No choices returned")
continue
}
fmt.Println("AI: ", resp.Choices[0].Message.Content)
file, err := os.OpenFile("output.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
if _, err := file.WriteString(resp.Choices[0].Message.Content + "\n"); err != nil {
fmt.Println("Error writing to file:", err)
}
messages = append(messages, resp.Choices[0].Message)
currLength := estimateTokenCount(messages)
if currLength > 95000 {
fmt.Println("Token count exceeded 95000, summarizing context")
summarized, err := summarizeChatSoFar(messages)
if err != nil {
fmt.Printf("error summarizing chat so far | %v\n", err)
continue
} else {
fmt.Printf("Summarized: %v\n", summarized)
}
// reset messages to the system prompt and the summarized prompt
messages = []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: systemPrompt,
},
{
Role: openai.ChatMessageRoleAssistant,
Content: summarized,
},
}
}
}
}
func estimateTokenCount(messages []openai.ChatCompletionMessage) int {
messagesRaw, err := json.Marshal(messages)
if err != nil {
fmt.Printf("error marshalling messages for token size estimation | %v\n", err)
return 0
}
length, err := LLMMapper.GetTokenCount(string(messagesRaw))
if err != nil {
fmt.Printf("error getting token count | %v\n", err)
return 0
}
fmt.Printf("Token Count: %v\n", length)
return length
}
func summarizeChatSoFar(messages []openai.ChatCompletionMessage) (string, error) {
messagesRaw, err := json.Marshal(messages)
if err != nil {
return "", fmt.Errorf("error marshalling messages for token size estimation | %w", err)
}
summarizeConvoPrompt, err := promptBuilder.BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100})
if err != nil {
return "", fmt.Errorf("error building prompt for summarization | %w", err)
}
resp, err := LLMMapper.SendPrompt([]openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: summarizeConvoPrompt,
},
{
Role: openai.ChatMessageRoleUser,
Content: string(messagesRaw),
},
})
if err != nil {
return "", fmt.Errorf("error summarizing conversation | %w", err)
}
if len(resp.Choices) == 0 {
return "", fmt.Errorf("no choices returned for summarization")
}
return resp.Choices[0].Message.Content, nil
}
// TODO: anything to be stored in the database should be chunked to sizes between 512 and 1024 tokens
// it should also overlap with the previous chunk by 100-200 tokens
// When the LLM asks for more context, it should be able to use the database to find the most relevant chunks here is how:
// We will get the embeddings for each prompt and use those embeddings to search for the closest 6 chunks
// we will use a separate LLM prompt to make an attempt to select and sort the chunks based on the user's input
// then we will add the best matched chunks to the main prompt as further context for the given prompt

31
cmd/rateTest/rate.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"fmt"
"sync"
"time"
)
type Rate struct {
RPM int
mu sync.Mutex
}
func main() {
r := Rate{RPM: 10}
for i := 0; i < 10; i++ {
go func(j int) {
r.RateLimit()
fmt.Println("Rate limiting")
}(i)
}
time.Sleep(time.Minute)
}
func (r *Rate) RateLimit() {
// Lock for the fraction of a minute based on RPM
r.mu.Lock()
// Unlock after the fraction of a minute
time.Sleep(time.Minute / time.Duration(r.RPM))
r.mu.Unlock()
}

View File

@ -9,7 +9,7 @@ import (
"zombiezen.com/go/sqlite/sqlitex" "zombiezen.com/go/sqlite/sqlitex"
) )
const dbLocation = "./context.db" const dbLocation = "./context.db" // TODO: put this in either a config or automatically place in the appData folder
var schema = sqlitemigration.Schema{ var schema = sqlitemigration.Schema{
// Each element of the Migrations slice is applied in sequence. When you // Each element of the Migrations slice is applied in sequence. When you

12
go.mod
View File

@ -3,17 +3,19 @@ module ctxGPT
go 1.19 go 1.19
require ( require (
github.com/pkoukk/tiktoken-go v0.1.6 github.com/pkoukk/tiktoken-go v0.1.7
github.com/sashabaranov/go-openai v1.36.1
zombiezen.com/go/sqlite v0.13.1 zombiezen.com/go/sqlite v0.13.1
) )
require ( require (
github.com/dlclark/regexp2 v1.10.0 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-isatty v0.0.16 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.5.0 // indirect github.com/stretchr/testify v1.8.3 // indirect
golang.org/x/sys v0.8.0 // indirect
modernc.org/libc v1.22.3 // indirect modernc.org/libc v1.22.3 // indirect
modernc.org/mathutil v1.5.0 // indirect modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect modernc.org/memory v1.5.0 // indirect

23
go.sum
View File

@ -1,23 +1,36 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw= github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
github.com/pkoukk/tiktoken-go v0.1.7 h1:qOBHXX4PHtvIvmOtyg1EeKlwFRiMKAcoMp4Q+bLQDmw=
github.com/pkoukk/tiktoken-go v0.1.7/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/sashabaranov/go-openai v1.17.9 h1:QEoBiGKWW68W79YIfXWEFZ7l5cEgZBV4/Ow3uy+5hNY=
github.com/sashabaranov/go-openai v1.17.9/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sashabaranov/go-openai v1.23.0 h1:KYW97r5yc35PI2MxeLZ3OofecB/6H+yxvSNqiT9u8is=
github.com/sashabaranov/go-openai v1.23.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sashabaranov/go-openai v1.36.1 h1:EVfRXwIlW2rUzpx6vR+aeIKCK/xylSrVYAx1TMTSX3g=
github.com/sashabaranov/go-openai v1.36.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY= modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw= modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=

35
main.go
View File

@ -1,17 +1,13 @@
package main package main
import ( import (
"bytes"
"context" "context"
"ctxGPT/LLMMapper"
"ctxGPT/database" "ctxGPT/database"
"ctxGPT/promptBuilder"
"fmt" "fmt"
"text/template"
"github.com/pkoukk/tiktoken-go"
) )
const encodingName = "gpt-4"
func main() { func main() {
db, err := database.NewDB() db, err := database.NewDB()
@ -33,37 +29,14 @@ func main() {
// to get text out of PDF, DOC, DOCX, XML, HTML, RTF, ODT pages documents and images to plain text // to get text out of PDF, DOC, DOCX, XML, HTML, RTF, ODT pages documents and images to plain text
// use https://github.com/sajari/docconv // use https://github.com/sajari/docconv
summarizeConvoPrompt, err := BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100}) summarizeConvoPrompt, err := promptBuilder.BuildPrompt("summarize.tmpl", struct{ WordLimit int }{WordLimit: 100})
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println(summarizeConvoPrompt) fmt.Println(summarizeConvoPrompt)
tokenCount, err := GetTokenCount(summarizeConvoPrompt) tokenCount, err := LLMMapper.GetTokenCount(summarizeConvoPrompt)
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println(tokenCount) fmt.Println(tokenCount)
} }
func BuildPrompt(name string, in interface{}) (string, error) {
fileLocation := "./prompts/" + name
tmpl, err := template.New(name).ParseFiles(fileLocation)
if err != nil {
return "", fmt.Errorf("error parsing template: %w", err)
}
b := bytes.Buffer{}
err = tmpl.Execute(&b, in)
if err != nil {
return "", fmt.Errorf("error executing template: %w", err)
}
return b.String(), nil
}
func GetTokenCount(input string) (int, error) {
tke, err := tiktoken.EncodingForModel(encodingName) // cached in "TIKTOKEN_CACHE_DIR"
if err != nil {
return 0, fmt.Errorf("error getting encoding: %w", err)
}
token := tke.Encode(input, nil, nil)
return len(token), nil
}

BIN
meilisearch.exe Normal file

Binary file not shown.

View File

@ -0,0 +1,21 @@
package promptBuilder
import (
"bytes"
"fmt"
"text/template"
)
func BuildPrompt(name string, in interface{}) (string, error) {
fileLocation := "./prompts/" + name
tmpl, err := template.New(name).ParseFiles(fileLocation)
if err != nil {
return "", fmt.Errorf("error parsing template: %w", err)
}
b := bytes.Buffer{}
err = tmpl.Execute(&b, in)
if err != nil {
return "", fmt.Errorf("error executing template: %w", err)
}
return b.String(), nil
}

View File

@ -0,0 +1,2 @@
{{.userPrompt}}
Let's think step by step.

View File

@ -0,0 +1 @@
Your job is to take a prompt from the user and generate a bash command or script to search for more context within files stored on the machine. Some previous conversations are stored in `/conversations`. Those conversations will fill in any gaps in your knowledge. Remember these conversations are free form. You'll need to allow for some fuzzy searching rather than using exact phrases. Feel free to use the best Linux tool available. Always respond with a bash command or script.

View File

@ -1,5 +1,5 @@
Your job is to summarize a history of previous messages in a conversation between an AI persona and a human. Your job is to summarize a history of previous messages in a conversation between an AI persona and a human.
The conversation you are given is a from a fixed context window and may not be complete. The conversation you are given is from a fixed context window and may not be complete.
Messages sent by the AI are marked with the 'assistant' role. Messages sent by the AI are marked with the 'assistant' role.
The AI 'assistant' can also make calls to functions, whose outputs can be seen in messages with the 'function' role. The AI 'assistant' can also make calls to functions, whose outputs can be seen in messages with the 'function' role.
Things the AI says in the message content are considered inner monologue and are not seen by the user. Things the AI says in the message content are considered inner monologue and are not seen by the user.

67
readme.md Normal file
View File

@ -0,0 +1,67 @@
# CTXGPT
Originally based on the idea of MemGPT, this project aims to augment the context of a given interaction with an LLM with a given context. Also, it is written in Golang.
### How it works
This project manages the context via various levels of storage.
The regular conversation between the user and the AI is stored in a full text searchable database. Since the context you can send to any given LLM is limited by number of tokens, the conversation will only contain the most recent messages. The AI has a few functions it can use to help it remember things beyond this limited context.
First, it has a function that will allow it to search the conversation history for a given string. This allows it to remember things that were said in the past.
It has a function that allows it to archive specific information in a concept=>definition relationship.
* I think it would be useful to allow the system to store sub-concepts as well. For example, if I tell the system about a specific person, it should be able to store that person's name, and other information about them. This would allow the system to remember things like "What is the name of the person who works at the coffee shop?".
It has a function that allows it to search the archived information for a given string. Which will load that information into its context window.
It can call a function to search the web, or a document database for specific information.
### Document Database
The document database is a collection of documents that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
The table contains the following fields:
* source - The source of the document (e.g. file path, wikipedia, or a specific website)
* checksum - The checksum of the document (used to determine if the document has changed)
* title - The title of the document
* content - The content of the document (parsed from the source into plain text)
* tags - A list of tags that can be used to search the document
* summary - A summary of the document (rolled up via GPT calls to compress the document into a few sentences)
* created_at - The date the document was created
* updated_at - The date the document was last updated
* needs_update - A flag that indicates if the document needs to be updated (e.g. if the source has changed)
### Conversation Database
The conversation database is a collection of messages that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
The table contains the following fields:
* source - The source of the message (e.g. user, system, LLM agent, etc.)
* content - The content of the message (parsed from the source into plain text)
* tags - A list of tags that can be used to search the message
* created_at - The date the message was created
### Concept Database
The concept database is a collection of concepts that are stored in a full text searchable database. The AI can search this database for specific information, and load it into its context window.
The table contains the following fields:
* concept - The concept that is being defined
* definition - The definition of the concept
* tags - A list of tags that can be used to search the concept
* created_at - The date the concept was created
* updated_at - The date the concept was last updated
### TODO
* [x] Set up a basic Database
* [ ] Create initial prompts for the LLM
* [ ] Create functions for the LLM to use to interact with the database
* [ ] Create conversational input/output handling for user interactions
* [ ] Create a way to ingest new documents and data into the database
* [ ] Manage rate limiting and errors from the LLM

128
transcript.md Normal file
View File

@ -0,0 +1,128 @@
You: Hey here. This is my first time trying a chat with you in my terminal.
AI: Welcome! It's great to have you trying out the chat in your terminal. Feel free to ask me questions or tell me what you need assistance with. Whether you're looking for information, technical help, or just a conversation, I'
m here to assist you. How can I help you today?
You: I am building an authentication application that developers can use to make their applications more secure. What do you think I should do in order to engender trust in the my application so they'll try it out?
AI: When building an authentication application that developers will trust and want to use, several key factors come into play. Here's a list of steps and strategies you can employ to build trust and encourage adoption:
1. **Security First**: Prioritize strong and up-to-date security practices within your application. Use the latest encryption standards, secure coding practices, and regularly audit your codebase for security vulnerabilities.
2. **Transparency**: Be transparent about your security practices. Publish your security measures, data handling policies, and compliance certifications if any. Openness about how you manage and protect user data can build signif
icant trust.
3. **Compliance**: Ensure that your application complies with relevant industry standards and regulations like GDPR, HIPAA, CCPA, and other data protection laws applicable to your users.
4. **Third-party Audits and Certifications**: Obtain audits from reputable security firms and pursue industry-recognized certifications to validate your security claims.
5. **Clear Documentation**: Provide comprehensive, clear, and accessible documentation for developers. Documentation should include integration guides, API references, best practices, and support resources.
6. **Developer Support**: Offer responsive and helpful support. This can include support tickets, community forums, chat support, and documentation to help resolve any issues quickly.
7. **
You: continue
AI: Open Source: If it's feasible for your business model, consider open-sourcing at least parts of your application. This allows developers to inspect the code themselves for security practices, which can significantly increase
trust. Transparency in your development process is often well-received within the developer community.
8. **Case Studies and Testimonials**: Share experiences of other developers and companies that have successfully integrated your authentication application. Real-world examples and endorsements can be powerful in demonstrating th
e reliability and benefits of your product.
9. **Free Tier or Trial Period**: Offering a free tier or a trial period can encourage developers to test your application without any financial commitment. This can help alleviate initial hesitation and allows them to directly a
ssess the quality and integration process.
10. **Easy Integration**: Make the integration process as straightforward as possible. The easier it is to use your application, the more likely developers will try it and stick with it.
11. **Marketing and Thought Leadership**: Create valuable content for developers blog posts, whitepapers, webinars, and tutorials that position you as a thought leader in authentication and security. Show your expertise and s
hare knowledge that can help developers beyond just using your service.
12. **Community Engagement**: Engage with the developer community through social media, tech conferences, meetups
You: continue
AI: , and hackathons. Being actively involved and visible in the community can help build your reputation and trust. Moreover, listening to feedback and incorporating it into your product's development demonstrates that you valu
e user input and are committed to continuous improvement.
13. **Partnerships**: Form partnerships with other trusted companies and organizations in the tech field. This not just extends your reach but also confers upon you a part of the trust that these entities have already established
.
14. **Reliability**: Ensure your authentication service is highly available and performs consistently. Downtime or performance issues can erode trust quickly, so invest in robust infrastructure and have a solid incident response
plan.
15. **Updates and Communication**: Keep your product up-to-date with the latest security trends and threats. Communicate proactively with your user base about new features, patches, and updates.
16. **User Authentication Options**: Provide various authentication methods such as multi-factor authentication, single sign-on, biometric verification, etc. Flexibility can make your application more appealing to a broader audie
nce.
17. **Privacy Policy**: Have a clear and concise privacy policy explaining how you handle and protect user data. Privacy is a major concern for many users and being upfront about it can aid in building trust.
18. **
You: it seems like you might have more
AI: Business and Pricing Model Clarity: Transparently explain your pricing model and business practices to avoid any hidden charges or surprises. Trust can be quickly eroded if customers feel they've been misled about the cost o
r terms of service.
19. **User Control and Consent**: Empower users with control over their data and require explicit consent where needed. When users feel in control of their data, they are more likely to trust your application.
20. **Feedback Loops**: Implement a system for users to provide feedback easily and make it clear that their input is valued and considered. This not only helps you improve your service but also demonstrates to users that you are
responsive and customer-centric.
21. **Bounty Programs**: Consider implementing a bug bounty program to encourage ethical hackers to report vulnerabilities in your system. This can help you identify and fix security issues before they are exploited and shows you
r commitment to security.
22. **Incremental Rollouts**: If viable, roll out your application incrementally, starting with beta testers or a limited audience. This allows you to gather initial feedback and make necessary improvements, thereby refining your
product before a full-scale launch.
Trust is essential in the world of security and authentication. By following the above strategies and maintaining a clear focus on quality and transparency, you can
You: continue once more
AI: build a strong foundation for trust with your customer base. Here are a few more things you can consider to engender trust in your authentication application:
23. **User Education and Resources**: Educate your users about security best practices and the importance of strong authentication. Provide resources such as guides and articles that explain security concepts in layman's terms. T
his can also involve training materials or webinars that teach users how to get the most out of your application.
24. **Data Breach Response Plan**: Have a clear and tested data breach response plan in place. Being able to react swiftly and transparently in the event of a breach can help maintain trust. It shows customers that you are prepar
ed and proactive in dealing with worst-case scenarios.
25. **Responsible Disclosure**: Encourage responsible disclosure of security issues by stating your policies clearly, including how you handle reports of security vulnerabilities, and possibly offering recognition or rewards for
those reports.
26. **Regular Security Updates and Patch Notes**: Regularly update your application with security patches and provide detailed notes on what was improved. Keeping your system up-to-date and informing users about changes can insti
ll confidence in your commitment to their security.
Remember, building trust is a long-term effort that involves consistent communication, a proactive stance on security, and
You:
------------------- Fixed the length issue ----------------------------------
Building trust in an authentication application is crucial because security is a top concern for developers and their users. Here are several steps you can take to engender trust in your application:
1. **Security First Design**: Ensure that your application is designed with security as a primary focus. Follow best practices for secure coding, and regularly audit and update your code to address any vulnerabilities.
2. **Transparency**: Be open about how your application works. Provide detailed documentation that explains the security measures you have implemented and how they protect your users.
3. **Third-Party Audits and Certifications**: Obtain security certifications from reputable organizations. Having your application's security audited by a third party can provide an unbiased validation of your security claims.
4. **Compliance with Standards**: Ensure your application complies with relevant security standards and regulations (e.g., OAuth 2.0, OpenID Connect, GDPR, HIPAA, etc.). Compliance demonstrates that you are serious about security
and privacy.
5. **Use of Well-Known Algorithms and Protocols**: Use industry-standard encryption algorithms and authentication protocols. Avoid proprietary or obscure methods that have not been thoroughly vetted by the security community.
6. **Open Source**: Consider making your application open source. This allows the community to review and contribute to your code, which can improve security and trustworthiness.
7. **Easy Integration**: Make it easy for developers to integrate your application into their systems. Provide SDKs, APIs, and clear documentation. If developers find it difficult to use your application, they are less likely to
trust it.
8. **Demonstrable Reliability**: Offer a reliable service with high uptime. Reliability is a key component of trust, and if your service is consistently available, developers are more likely to trust it.
9. **Customer Support**: Provide excellent customer support. Be responsive to inquiries and issues. If developers feel supported, they are more likely to trust your application.
10. **Case Studies and Testimonials**: Share success stories from other developers who have successfully implemented your application. Testimonials from satisfied users can be very persuasive.
11. **Free Trial or Freemium Model**: Offer a free trial or a freemium version of your application. This allows developers to test your application and see its benefits firsthand without any financial commitment.
12. **Marketing and Branding**: Invest in professional marketing and branding. A strong brand can convey trustworthiness and professionalism.
13. **Community Engagement**: Engage with the developer community through forums, social media, conferences, and hackathons. Building relationships with developers can lead to trust and word-of-mouth recommendations.
14. **Educational Content**: Provide educational content that helps developers understand security concepts and best practices. This positions you as an expert in the field and builds trust in your application.
15. **Regular Updates and Communication**: Keep your application up-to-date with the latest security features and communicate these updates to your users. Regular communication about improvements demonstrates your commitment to s
ecurity.
Remember, building trust takes time and consistent effort. By focusing on security, transparency, and user support, you can create a strong foundation of trust for your authentication application.