From 8c1fc80e5b089038ad85d358fc96cb3a51f281ec Mon Sep 17 00:00:00 2001 From: calvinmvrk Date: Thu, 7 Nov 2024 16:30:31 -0600 Subject: [PATCH 1/3] add stream cmd --- cmd/chat.go | 8 +----- cmd/rootCmd.go | 32 +++++++++++++++++++++ cmd/stream.go | 38 +++++++++++++++++++++++++ pkg/stream/parse.go | 68 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 cmd/rootCmd.go create mode 100644 cmd/stream.go create mode 100644 pkg/stream/parse.go diff --git a/cmd/chat.go b/cmd/chat.go index e324199..e1a84e1 100644 --- a/cmd/chat.go +++ b/cmd/chat.go @@ -20,6 +20,7 @@ const ( ) var chatCmd = &cobra.Command{ + Use: "chat", Short: "Interact with your agent.", Long: `This cli tool allows you to debug your agent by chatting with it locally.`, Run: agentChat, @@ -74,10 +75,3 @@ func agentChat(cmd *cobra.Command, args []string) { fmt.Println(err) } } - -func Execute() { - err := chatCmd.Execute() - if err != nil { - os.Exit(1) - } -} diff --git a/cmd/rootCmd.go b/cmd/rootCmd.go new file mode 100644 index 0000000..ee6a289 --- /dev/null +++ b/cmd/rootCmd.go @@ -0,0 +1,32 @@ +// rootCmd.go +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + // "github.com/github-technology-partners/gh-debug-cli/cmd/stream" +) + +var rootCmd = &cobra.Command{ + Use: "gh-debug-cli", + Short: "A CLI tool for debugging", + Long: `This CLI tool allows you to debug your agent by chatting with it locally.`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Use 'gh-debug-cli --help' to see available commands") + }, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + // Add subcommands to rootCmd + rootCmd.AddCommand(chatCmd) + rootCmd.AddCommand(streamCmd) +} diff --git a/cmd/stream.go b/cmd/stream.go new file mode 100644 index 0000000..24bf21b --- /dev/null +++ b/cmd/stream.go @@ -0,0 +1,38 @@ +// stream.go +package cmd + +import ( + "fmt" + "os" + + "github.com/github-technology-partners/gh-debug-cli/pkg/stream" + "github.com/spf13/cobra" +) + +const ( + streamCmdFileFlag = "file" +) + +// streamCmd represents the new command for streaming functionality +var streamCmd = &cobra.Command{ + Use: "stream [file]", + Short: "Stream data to your agent", + Long: `The stream command allows you to initiate a data stream to your agent.`, + Run: agentStream, +} + +func init() { + streamCmd.PersistentFlags().String(streamCmdFileFlag, "", "Parse agent responses from a file") +} + +func agentStream(cmd *cobra.Command, args []string) { + fmt.Println("stream command executed successfully") + + file := args[0] + + err := stream.ParseFile(file) + if err != nil { + fmt.Fprintf(os.Stderr, "Error parsing file: %v\n", err) + os.Exit(1) + } +} diff --git a/pkg/stream/parse.go b/pkg/stream/parse.go new file mode 100644 index 0000000..5a71430 --- /dev/null +++ b/pkg/stream/parse.go @@ -0,0 +1,68 @@ +package stream + +import ( + "bufio" + "encoding/json" + "fmt" + "os" + "strings" +) + +type Choice struct { + Delta struct { + Content string `json:"content"` + } `json:"delta"` +} + +type Data struct { + Choices []Choice `json:"choices"` +} + +func ParseFile(filename string) error { + // Open the file + file, err := os.Open(filename) + if err != nil { + return fmt.Errorf("could not open file: %w", err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + var contentBuilder strings.Builder + + for scanner.Scan() { + line := scanner.Text() + + // Check if the line has "data: " prefix + if strings.HasPrefix(line, "data: ") { + // Remove the "data: " prefix + line = strings.TrimPrefix(line, "data: ") + } else { + continue // skip lines without "data: " + } + + // Parse the JSON line into our `Data` struct + var data Data + err := json.Unmarshal([]byte(line), &data) + if err != nil { + // Skip this line if JSON is incomplete or malformed + // fmt.Fprintf(os.Stderr, "Warning: could not parse JSON: %v\n", err) + continue + } + + // Extract delta.content and concatenate it + for _, choice := range data.Choices { + contentBuilder.WriteString(choice.Delta.Content) + } + } + + // Check for scanner errors + if err := scanner.Err(); err != nil { + return fmt.Errorf("error reading file: %w", err) + } + + // Print the final concatenated result + result := contentBuilder.String() + fmt.Println(result) + + return nil +} From c08602f5a1dfa5f07fa539a6b49335df37522da5 Mon Sep 17 00:00:00 2001 From: calvinmvrk Date: Thu, 7 Nov 2024 16:41:00 -0600 Subject: [PATCH 2/3] remove comments --- cmd/rootCmd.go | 1 - pkg/stream/parse.go | 1 - 2 files changed, 2 deletions(-) diff --git a/cmd/rootCmd.go b/cmd/rootCmd.go index ee6a289..64b6c1a 100644 --- a/cmd/rootCmd.go +++ b/cmd/rootCmd.go @@ -6,7 +6,6 @@ import ( "os" "github.com/spf13/cobra" - // "github.com/github-technology-partners/gh-debug-cli/cmd/stream" ) var rootCmd = &cobra.Command{ diff --git a/pkg/stream/parse.go b/pkg/stream/parse.go index 5a71430..adb1b3e 100644 --- a/pkg/stream/parse.go +++ b/pkg/stream/parse.go @@ -45,7 +45,6 @@ func ParseFile(filename string) error { err := json.Unmarshal([]byte(line), &data) if err != nil { // Skip this line if JSON is incomplete or malformed - // fmt.Fprintf(os.Stderr, "Warning: could not parse JSON: %v\n", err) continue } From 1ce721154e90a7f14985099d866a69aae16d198e Mon Sep 17 00:00:00 2001 From: calvinmvrk Date: Fri, 8 Nov 2024 13:05:23 -0600 Subject: [PATCH 3/3] address comments for edge cases --- pkg/stream/parse.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/stream/parse.go b/pkg/stream/parse.go index adb1b3e..e1929ae 100644 --- a/pkg/stream/parse.go +++ b/pkg/stream/parse.go @@ -40,6 +40,14 @@ func ParseFile(filename string) error { continue // skip lines without "data: " } + // Handle special cases + if line == "[DONE]" { + break // stop processing if we encounter [DONE] + } + if line == "" { + continue // skip empty data lines + } + // Parse the JSON line into our `Data` struct var data Data err := json.Unmarshal([]byte(line), &data)