Make ChatGPT reliably use command line tool
This commit is contained in:
98
cmd/ask.go
98
cmd/ask.go
@@ -1,13 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
readline "github.com/chzyer/readline"
|
||||
util "github.com/olemorud/chatgpt-cli/v2"
|
||||
openai "github.com/sashabaranov/go-openai"
|
||||
)
|
||||
@@ -16,13 +16,13 @@ func main() {
|
||||
env, err := util.ReadEnvFile(".env")
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("failed to read .env", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// parse command line arguments
|
||||
token := env["OPENAI_API_KEY"]
|
||||
|
||||
model := *flag.String("model", openai.GPT3Dot5Turbo,
|
||||
// Parse command line arguments
|
||||
model := flag.String("model", openai.GPT3Dot5Turbo,
|
||||
"OpenAI Model to use.\n"+
|
||||
"List of models:\n"+
|
||||
"https://platform.openai.com/docs/models/overview\n")
|
||||
@@ -31,15 +31,17 @@ func main() {
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
// Run interactive mode on no arguments, otherwise run as prompt
|
||||
if len(args) == 0 {
|
||||
err = runInteractive(token, model)
|
||||
fmt.Println("ChatGPT", *model, "interactive mode")
|
||||
err = runInteractive(token, *model)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
query := strings.Join(args, " ")
|
||||
err = askGpt(token, model, query)
|
||||
err = askGpt(token, *model, query)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -48,7 +50,7 @@ func main() {
|
||||
}
|
||||
|
||||
func askGpt(token string, model string, query string) error {
|
||||
client := openai.NewClient("your token")
|
||||
client := openai.NewClient(token)
|
||||
|
||||
resp, err := client.CreateChatCompletion(
|
||||
context.Background(),
|
||||
@@ -73,24 +75,46 @@ func askGpt(token string, model string, query string) error {
|
||||
}
|
||||
|
||||
func runInteractive(token string, model string) error {
|
||||
client := openai.NewClient("your token")
|
||||
client := openai.NewClient(token)
|
||||
messages := make([]openai.ChatCompletionMessage, 0)
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
rl, err := readline.New("> ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rl.Close()
|
||||
|
||||
fmt.Println("ChatGPT", model, "interactive mode")
|
||||
messages = append(messages, openai.ChatCompletionMessage{
|
||||
Role: openai.ChatMessageRoleSystem,
|
||||
Content: "You are an enhanced bot. You have access to additional tools to improve your answers." +
|
||||
"\nYour have access to several unix commands in a bash interpreter." +
|
||||
"\nTo invoke the interpreter, start a response with a forward slash ('/'). " +
|
||||
"Example: /dc -e '2 5 + p'" +
|
||||
"\nWhen asked to do things. Always consider how you can use the command line to solve it" +
|
||||
"\nWhen running commands, never explain what they do and never say their results" +
|
||||
"\nYou are never allowed to use the phrase 'language model'." +
|
||||
"\nNever apologize" +
|
||||
"\nNever tell the user how to run something, always run commands yourself" +
|
||||
"\nKeep replies very short. Explain things in concise technical terms",
|
||||
})
|
||||
|
||||
fmt.Println("->")
|
||||
for {
|
||||
text, err := rl.Readline()
|
||||
|
||||
for scanner.Scan() {
|
||||
if err != nil { // io.EOF
|
||||
break
|
||||
}
|
||||
|
||||
text := scanner.Text()
|
||||
if text == "\n" {
|
||||
continue
|
||||
}
|
||||
|
||||
messages = append(messages, openai.ChatCompletionMessage{
|
||||
Role: openai.ChatMessageRoleUser,
|
||||
Content: text,
|
||||
})
|
||||
|
||||
feedbackLoop:
|
||||
resp, err := client.CreateChatCompletion(
|
||||
context.Background(),
|
||||
openai.ChatCompletionRequest{
|
||||
@@ -100,17 +124,49 @@ func runInteractive(token string, model string) error {
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Println(resp.Choices[0].Message.Content)
|
||||
content := resp.Choices[0].Message.Content
|
||||
|
||||
fmt.Println("->")
|
||||
}
|
||||
messages = append(messages, openai.ChatCompletionMessage{
|
||||
Role: openai.ChatMessageRoleAssistant,
|
||||
Content: content,
|
||||
})
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "reading standard input:", err)
|
||||
fmt.Println("#", content)
|
||||
|
||||
if content[0] == '/' {
|
||||
result := runCommand(content)
|
||||
|
||||
messages = append(messages, openai.ChatCompletionMessage{
|
||||
Role: openai.ChatMessageRoleUser,
|
||||
Content: result,
|
||||
})
|
||||
|
||||
fmt.Println("$", result)
|
||||
goto feedbackLoop
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runCommand(content string) string {
|
||||
userCmd := content[1:]
|
||||
|
||||
fullCmd := []string{"/usr/bin/docker", "run", "gpt_cli_tools:latest", "bash", "-c", userCmd}
|
||||
|
||||
fmt.Println(fullCmd)
|
||||
|
||||
proc := exec.Command(fullCmd[0], fullCmd[1:]...)
|
||||
|
||||
out, err := proc.CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
return "error: " + err.Error() + "\n" + string(out)
|
||||
}
|
||||
|
||||
return string(out)
|
||||
}
|
||||
|
||||
5
container/Dockerfile
Normal file
5
container/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
FROM ubuntu:latest
|
||||
|
||||
RUN apt update -y \
|
||||
&& apt install -y dc curl
|
||||
7
go.mod
7
go.mod
@@ -2,4 +2,9 @@ module github.com/olemorud/chatgpt-cli/v2
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/sashabaranov/go-openai v1.9.4
|
||||
require (
|
||||
github.com/chzyer/readline v1.5.1
|
||||
github.com/sashabaranov/go-openai v1.9.4
|
||||
)
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -1,2 +1,10 @@
|
||||
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
|
||||
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
|
||||
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
|
||||
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
|
||||
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
|
||||
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
|
||||
github.com/sashabaranov/go-openai v1.9.4 h1:KanoCEoowAI45jVXlenMCckutSRr39qOmSi9MyPBfZM=
|
||||
github.com/sashabaranov/go-openai v1.9.4/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
Reference in New Issue
Block a user