From c7896e47f9c91e330b023bdb34a7540f193a5422 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 30 Aug 2025 15:15:43 -0500 Subject: code cleanup of early drafts of code from Gemini AI --- .gitignore | 1 + Makefile | 4 +-- argv.go | 27 +++++---------- argvAutoshell.go | 4 +-- doConnect.go | 31 ++++------------- doEditor.go | 92 --------------------------------------------------- doGetNextAutoTopic.go | 3 -- doImport.go | 56 ------------------------------- doInput.go | 56 ------------------------------- doInteract.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ doNewChat.go | 2 +- doStats.go | 8 ++--- main.go | 79 +++++++++++++++---------------------------- 13 files changed, 141 insertions(+), 314 deletions(-) delete mode 100644 doEditor.go delete mode 100644 doImport.go delete mode 100644 doInput.go create mode 100644 doInteract.go diff --git a/.gitignore b/.gitignore index eac6b71..0f16656 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ go.sum /resources/*.so /files/* regex +/tmp/* diff --git a/Makefile b/Makefile index b2398ce..091bbd2 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = $(shell git describe --tags) BUILDTIME = $(shell date +%Y.%m.%d_%H%M) default: install - regex --json /tmp/regex.55128216-e93b-4339-8854-622ca11af890.gemini-api-request.99.json connect + regex --json /tmp/regex.55128216-e93b-4339-8854-622ca11af890.gemini-api-request.128.json vet: @GO111MODULE=off go vet @@ -55,5 +55,5 @@ playback: regex playback # regex playback --uuid a1b2c3d4-e5f6-4a5b-8c9d-1e2f3a4b5c6d -tmp: +tmpfiles: ls -tl /tmp/regex.* |head diff --git a/argv.go b/argv.go index 973f616..e6c4c0b 100644 --- a/argv.go +++ b/argv.go @@ -10,24 +10,15 @@ package main var argv args type args struct { - Add string `arg:"--add" help:"add a new chat"` - Format *EmptyCmd `arg:"subcommand:format" help:"add a conversation"` - Connect *EmptyCmd `arg:"subcommand:connect" help:"connect to gemini AI"` - Playback *PlaybackCmd `arg:"subcommand:playback" help:"dump your prior conversations to the terminal'"` - Output string `arg:"--output" help:"should get a string from regex-cli"` - Input string `arg:"--input" help:"should get a string from regex-cli"` - Editor *EmptyCmd `arg:"subcommand:interact" help:"open env EDITOR"` - ImportFile string `arg:"--import" help:"import a file from regex-cli"` - JsonFile string `arg:"--json" help:"import a JSON file from gemini-cli"` - Uuid string `arg:"--uuid" help:"look at this uuid"` - Topic string `arg:"--topic" help:"the topic"` - Stats []string `arg:"--stats" help:"add stats to a chat"` - NewChat *EmptyCmd `arg:"subcommand:newchat" help:"create a new chat"` - GetNextAutoTopic bool `arg:"--get-next-auto-topic" help:"get the next auto topic name"` - Force bool `arg:"--force" help:"try to strong arm things"` - Verbose bool `arg:"--verbose" help:"show more output"` - Bash bool `arg:"--bash" help:"generate bash completion"` - BashAuto []string `arg:"--auto-complete" help:"todo: move this to go-arg"` + Uuid string `arg:"--uuid" help:"look at this uuid"` + JsonFile string `arg:"--json" help:"import a JSON file from gemini-cli"` + Interact *EmptyCmd `arg:"subcommand:interact" help:"open env EDITOR"` + Playback *PlaybackCmd `arg:"subcommand:playback" help:"dump your prior conversations to the terminal'"` + Stats string `arg:"--stats" help:"add stats to a chat"` + Force bool `arg:"--force" help:"try to strong arm things"` + Verbose bool `arg:"--verbose" help:"show more output"` + Bash bool `arg:"--bash" help:"generate bash completion"` + BashAuto []string `arg:"--auto-complete" help:"todo: move this to go-arg"` } type EmptyCmd struct { diff --git a/argvAutoshell.go b/argvAutoshell.go index 4bdb79d..3611411 100644 --- a/argvAutoshell.go +++ b/argvAutoshell.go @@ -21,7 +21,7 @@ func deleteMatch() { } func (args) doBashAuto() { - argv.doBashHelp() + // argv.doBashHelp() switch argv.BashAuto[0] { case "playback": fmt.Println("long --uuid") @@ -30,7 +30,7 @@ func (args) doBashAuto() { default: if argv.BashAuto[0] == ARGNAME { // list the subcommands here - fmt.Println("--add connect format interact playback") + fmt.Println("--json interact playback") } } os.Exit(0) diff --git a/doConnect.go b/doConnect.go index 2285f0b..b7abd40 100644 --- a/doConnect.go +++ b/doConnect.go @@ -10,42 +10,23 @@ import ( ) // doConnect initializes the Gemini client and handles the request flow. -func doConnect() error { +func doConnect() (*genai.Client, error) { apiKey := os.Getenv("GEMINI_API_KEY") if apiKey == "" { - return log.Errorf("GEMINI_API_KEY environment variable not set") + return nil, log.Errorf("GEMINI_API_KEY environment variable not set") } ctx := context.Background() client, err := genai.NewClient(ctx, &genai.ClientConfig{APIKey: apiKey}) if err != nil { - return log.Errorf("failed to create new genai client: %w", err) + return nil, log.Errorf("failed to create new genai client: %w", err) } - if argv.JsonFile != "" { - req, err := parseJSON(argv.JsonFile) - if err != nil { - return err - } - log.Info("parseJSON() ok. model =", req.Model) - - genaiContent, err := convertToGenai(req) - if err != nil { - return log.Errorf("failed to convert to genai.Content: %w", err) - } - log.Info("Successfully converted JSON to genai.Content") - // Here you would now use the 'genaiContent' to send to the API - _ = genaiContent // Prevent unused variable error for now - - return nil - } - - log.Info("doing sampleHello()") - return sampleHello(client) + return client, err } // sampleHello sends a hardcoded prompt to the model and prints the response. -func sampleHello(client *genai.Client) error { +func simpleHello(client *genai.Client) error { log.Info("Sending 'hello, how are you' to the Gemini API...") ctx := context.Background() @@ -56,7 +37,7 @@ func sampleHello(client *genai.Client) error { content := []*genai.Content{{Parts: parts}} - resp, err := client.Models.GenerateContent(ctx, "gemini-1.5-flash-latest", content, nil) + resp, err := client.Models.GenerateContent(ctx, "gemini-2.5-flash", content, nil) if err != nil { return log.Errorf("error sending message: %v", err) } diff --git a/doEditor.go b/doEditor.go deleted file mode 100644 index acaf75c..0000000 --- a/doEditor.go +++ /dev/null @@ -1,92 +0,0 @@ -package main - -import ( - "io/ioutil" - "os" - "os/exec" - "strings" - "time" - - "go.wit.com/log" -) - -func doEditor() error { - for { - filename, err := doEditorOnce() - if err != nil { - return err - } - log.Info("filename:", filename) - - for { - _, err := os.Stat("/tmp/regex.ready") - if err == nil { - break - } - time.Sleep(100 * time.Millisecond) - } - // read in regex.ready exists (should be SessionID) - // Println session ID - content, err := ioutil.ReadFile("/tmp/regex.ready") - if err != nil { - log.Error(err) - } - os.Remove("/tmp/regex.ready") - log.Info("SessionID: %s", string(content)) - - logContent, err := ioutil.ReadFile("/tmp/regex.log") - if err != nil { - log.Errorf("could not read regex.log: %v", err) - } else { - log.Info("contents of /tmp/regex.log:") - os.Stdout.Write(logContent) - } - - time.Sleep(5 * time.Second) - } -} - -func doEditorOnce() (string, error) { - // Create a temporary file - tmpfile, err := ioutil.TempFile("", "regex-*.txt") - if err != nil { - return "", err - } - tmpPath := tmpfile.Name() - // Defer removal in case of error, but we might move it - defer os.Remove(tmpPath) - tmpfile.Close() - - // Get the user's editor - editor := os.Getenv("EDITOR") - if editor == "" { - editor = "vim" // default to vim - } - - // Run the editor - cmd := exec.Command(editor, tmpPath) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - if err := cmd.Run(); err != nil { - return "", err - } - - // Read the file content - content, err := ioutil.ReadFile(tmpPath) - if err != nil { - return "", err - } - - // Check if the file is not empty after trimming space - if strings.TrimSpace(string(content)) != "" { - // Move the file - if err := os.Rename(tmpPath, "/tmp/regex.txt"); err != nil { - return "", err - } - return "/tmp/regex.txt", nil - } - - return "", nil -} diff --git a/doGetNextAutoTopic.go b/doGetNextAutoTopic.go index 647d209..75060a7 100644 --- a/doGetNextAutoTopic.go +++ b/doGetNextAutoTopic.go @@ -8,9 +8,6 @@ import ( ) func doGetNextAutoTopic() { - if err := me.chats.ConfigLoad(); err != nil { - badExit(err) - } max := 0 for _, chat := range me.chats.GetChats() { if strings.HasPrefix(chat.GetChatName(), "Auto ") { diff --git a/doImport.go b/doImport.go deleted file mode 100644 index def0071..0000000 --- a/doImport.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "io/ioutil" - "time" - - "go.wit.com/lib/protobuf/chatpb" - "go.wit.com/log" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func doImport(filename string) { - content, err := ioutil.ReadFile(filename) - if err != nil { - log.Warn("Error reading import file:", err) - return - } - - s := string(content) - - // Load the existing chats. - all := chatpb.NewChats() - if err := all.ConfigLoad(); err != nil { - log.Warn("Error loading config, can't add to auto chat:", err) - return - } - - // Find the "auto" chat. - var autoChat *chatpb.Chat - for _, chat := range all.GetChats() { - if chat.GetChatName() == "auto" { - autoChat = chat - break - } - } - - // If the "auto" chat is found, add the new entry. - if autoChat != nil { - newEntry := &chatpb.ChatEntry{ - From: chatpb.Who_REGEX, - Ctime: timestamppb.New(time.Now()), - ToolCalls: []*chatpb.ToolCall{ - { - Name: "Shell", - Input: s, - }, - }, - } - autoChat.Entries = append(autoChat.Entries, newEntry) - if err := all.ConfigSave(); err != nil { - log.Warn("Error saving config after adding to auto chat:", err) - } else { - log.Info("Added new entry to 'auto' chat.") - } - } -} diff --git a/doInput.go b/doInput.go deleted file mode 100644 index fe7cf21..0000000 --- a/doInput.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "os" - "time" - - "go.wit.com/lib/protobuf/chatpb" - "go.wit.com/log" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func doInput(s string) { - filename := "/tmp/regex-input.log" - f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Println(err) - return - } - defer f.Close() - if _, err := f.WriteString(s + "\n"); err != nil { - log.Println(err) - } - - log.Info("INPUT LOGGED TO", filename) - - // Load the existing chats. - all := chatpb.NewChats() - if err := all.ConfigLoad(); err != nil { - log.Warn("Error loading config, can't add to auto chat:", err) - return - } - - // Find the "auto" chat. - var autoChat *chatpb.Chat - for _, chat := range all.GetChats() { - if chat.GetChatName() == "auto" { - autoChat = chat - break - } - } - - // If the "auto" chat is found, add the new entry. - if autoChat != nil { - newEntry := &chatpb.ChatEntry{ - From: chatpb.Who_USER, - Content: s, - Ctime: timestamppb.New(time.Now()), - } - autoChat.Entries = append(autoChat.Entries, newEntry) - if err := all.ConfigSave(); err != nil { - log.Warn("Error saving config after adding to auto chat:", err) - } else { - log.Info("Added new entry to 'auto' chat.") - } - } -} diff --git a/doInteract.go b/doInteract.go new file mode 100644 index 0000000..f99b3d9 --- /dev/null +++ b/doInteract.go @@ -0,0 +1,92 @@ +package main + +import ( + "io/ioutil" + "os" + "os/exec" + "strings" + "time" + + "go.wit.com/log" +) + +func doInteract() error { + for { + filename, err := doEditorOnce() + if err != nil { + return err + } + log.Info("filename:", filename) + + for { + _, err := os.Stat("/tmp/regex.ready") + if err == nil { + break + } + time.Sleep(100 * time.Millisecond) + } + // read in regex.ready exists (should be SessionID) + // Println session ID + content, err := ioutil.ReadFile("/tmp/regex.ready") + if err != nil { + log.Error(err) + } + os.Remove("/tmp/regex.ready") + log.Info("SessionID: %s", string(content)) + + logContent, err := ioutil.ReadFile("/tmp/regex.log") + if err != nil { + log.Errorf("could not read regex.log: %v", err) + } else { + log.Info("contents of /tmp/regex.log:") + os.Stdout.Write(logContent) + } + + time.Sleep(5 * time.Second) + } +} + +func doEditorOnce() (string, error) { + // Create a temporary file + tmpfile, err := ioutil.TempFile("", "regex-*.txt") + if err != nil { + return "", err + } + tmpPath := tmpfile.Name() + // Defer removal in case of error, but we might move it + defer os.Remove(tmpPath) + tmpfile.Close() + + // Get the user's editor + editor := os.Getenv("EDITOR") + if editor == "" { + editor = "vim" // default to vim + } + + // Run the editor + cmd := exec.Command(editor, tmpPath) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return "", err + } + + // Read the file content + content, err := ioutil.ReadFile(tmpPath) + if err != nil { + return "", err + } + + // Check if the file is not empty after trimming space + if strings.TrimSpace(string(content)) != "" { + // Move the file + if err := os.Rename(tmpPath, "/tmp/regex.txt"); err != nil { + return "", err + } + return "/tmp/regex.txt", nil + } + + return "", nil +} diff --git a/doNewChat.go b/doNewChat.go index f9793d1..adb0ee3 100644 --- a/doNewChat.go +++ b/doNewChat.go @@ -9,7 +9,7 @@ import ( func doNewChat() { chat := &chatpb.Chat{ Uuid: argv.Uuid, - ChatName: argv.Topic, + ChatName: "todo: set this", Ctime: timestamppb.Now(), } diff --git a/doStats.go b/doStats.go index 3013c97..01fc0d6 100644 --- a/doStats.go +++ b/doStats.go @@ -9,12 +9,8 @@ import ( ) func doStats() { - if len(argv.Stats) != 2 { - log.Warn("expected 2 arguments for --stats") - return - } - sessionUuid := argv.Stats[0] - statsString := argv.Stats[1] + sessionUuid := argv.Uuid + statsString := "todo: set this somehow" // Find the "auto" chat, or create it if it doesn't exist. var autoChat *chatpb.Chat diff --git a/main.go b/main.go index 6f91f27..16c2ea7 100644 --- a/main.go +++ b/main.go @@ -47,70 +47,54 @@ func main() { os.Exit(0) } + // load the default chat protobuf me.chats = chatpb.NewChats() if err := me.chats.ConfigLoad(); err != nil { badExit(err) } + + // verify all the chats have Uuid's if verifyUuids(me.chats) { me.chats.ConfigSave() } - if argv.GetNextAutoTopic { - doGetNextAutoTopic() - okExit("") + aiClient, err := doConnect() + if err != nil { + badExit(err) } + _ = aiClient - if argv.Connect != nil { - err := doConnect() + if argv.JsonFile != "" { + req, err := parseJSON(argv.JsonFile) if err != nil { badExit(err) } - okExit("") - } - - if argv.Editor != nil { - doEditor() - okExit("") - } - - if argv.NewChat != nil { - doNewChat() - okExit("") - } - - if argv.Stats != nil { - doStats() - okExit("") - } + log.Info("parseJSON() ok. model =", req.Model) - if argv.Output != "" { - doOutput(argv.Output) - okExit("") - } - - if argv.Input != "" { - doInput(argv.Input) - okExit("") - } + genaiContent, err := convertToGenai(req) + if err != nil { + badExit(err) + } + log.Info("Successfully converted JSON to genai.Content") + // Here you would now use the 'genaiContent' to send to the API + _ = genaiContent // Prevent unused variable error for now - if argv.ImportFile != "" { - doImport(argv.ImportFile) okExit("") } - if argv.Add != "" { - newChats, err := addFile(argv.Add) + if argv.Interact != nil { + log.Info("testing AI client with simpleHello()") + err = simpleHello(aiClient) if err != nil { badExit(err) } - verifyUuids(newChats) - for _, newChat := range newChats.GetChats() { - me.chats.AppendByUuid(newChat) - log.Info("Attempting to add chat", newChat.ChatName) - } + doInteract() + okExit("") + } - me.chats.ConfigSave() + if argv.Stats != "" { + doStats() okExit("") } @@ -123,21 +107,10 @@ func main() { okExit("") } - /* - // if opening the GUI, always check git for dirty repos - log.Info("look for 'auto' here") - // Find the "auto" chat. - for _, chat := range me.chats.GetChats() { - if chat.GetChatName() == "auto" { - prettyFormatChat(chat) - okExit("") - } - } - */ // doGui() // by default, start interacting with gemini-cli - doEditor() + me.pp.WriteHelp(os.Stdout) okExit("") } -- cgit v1.2.3