Skip to content

Commit 70b3313

Browse files
committed
Improve ask, add verbose mode on some commands
1 parent 67458c9 commit 70b3313

File tree

7 files changed

+122
-35
lines changed

7 files changed

+122
-35
lines changed

cmd/ask.go

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,29 @@ import (
77
"fmt"
88
"os"
99
"path/filepath"
10+
"sort"
1011
"strings"
1112

13+
"github.com/chand1012/git2gpt/prompt"
1214
"github.com/chand1012/memory"
15+
l "github.com/charmbracelet/log"
1316
"github.com/spf13/cobra"
1417

1518
"github.com/chand1012/ottodocs/pkg/ai"
19+
"github.com/chand1012/ottodocs/pkg/calc"
1620
"github.com/chand1012/ottodocs/pkg/config"
1721
"github.com/chand1012/ottodocs/pkg/git"
1822
"github.com/chand1012/ottodocs/pkg/utils"
1923
)
2024

25+
// move this to memory package eventually
26+
func sortByScore(fragments []memory.MemoryFragment) []memory.MemoryFragment {
27+
sort.Slice(fragments, func(i, j int) bool {
28+
return fragments[i].Score > fragments[j].Score
29+
})
30+
return fragments
31+
}
32+
2133
// askCmd represents the ask command
2234
var askCmd = &cobra.Command{
2335
Use: "ask",
@@ -30,7 +42,13 @@ Requires a path to a repository or file as a positional argument.`,
3042
}
3143
return nil
3244
}),
45+
PreRun: func(cmd *cobra.Command, args []string) {
46+
if verbose {
47+
log.SetLevel(l.DebugLevel)
48+
}
49+
},
3350
Run: func(cmd *cobra.Command, args []string) {
51+
var answer string
3452
repoPath := args[0]
3553
var fileName string
3654
conf, err := config.Load()
@@ -42,12 +60,14 @@ Requires a path to a repository or file as a positional argument.`,
4260
}
4361

4462
if chatPrompt == "" {
63+
log.Debug("User did not enter a question. Prompting for one...")
4564
fmt.Println("Please enter a question: ")
4665
fmt.Scanln(&chatPrompt)
4766
// strip the newline character
4867
chatPrompt = strings.TrimRight(chatPrompt, " \n")
4968
}
5069

70+
log.Debug("Getting file contents...")
5171
info, err := os.Stat(repoPath)
5272
if err != nil {
5373
log.Errorf("Error getting file info: %s", err)
@@ -56,16 +76,19 @@ Requires a path to a repository or file as a positional argument.`,
5676
// check if the first arg is a file or a directory
5777
// if it's a file, ask a question about that file directly
5878
if info.IsDir() {
79+
log.Debug("Constructing repo memory...")
5980
// Define a temporary path for the index file
6081
testIndexPath := filepath.Join(args[0], ".index.memory")
6182

83+
log.Debug("Creating memory index...")
6284
// Create a new memory index
6385
m, _, err := memory.New(testIndexPath)
6486
if err != nil {
6587
log.Errorf("Failed to create memory index: %s", err)
6688
os.Exit(1)
6789
}
6890

91+
log.Debug("Indexing repo...")
6992
// index the repo
7093
repo, err := git.GetRepo(repoPath, ignoreFilePath, ignoreGitignore)
7194
if err != nil {
@@ -82,38 +105,75 @@ Requires a path to a repository or file as a positional argument.`,
82105
}
83106
}
84107

108+
log.Debug("Searching memory index...")
85109
// search the memory index
86110
results, err := m.Search(chatPrompt)
87111
if err != nil {
88112
log.Errorf("Failed to search memory index: %s", err)
89113
os.Exit(1)
90114
}
91115

116+
log.Debug("Results extracted. Destroying memory index...")
117+
// close the memory index
92118
m.Destroy()
93119

94-
// get the top fragment by average score
95-
top := memory.TopFragmentAvg(results)
96-
fileName = top.ID
120+
log.Debug("Sorting results...")
121+
sortedFragments := sortByScore(results)
122+
123+
log.Debug("Getting file contents...")
124+
var files []prompt.GitFile
125+
for _, result := range sortedFragments {
126+
for _, file := range repo.Files {
127+
if file.Path == result.ID {
128+
files = append(files, file)
129+
}
130+
}
131+
}
132+
133+
if len(files) == 0 {
134+
log.Error("No results found.")
135+
os.Exit(1)
136+
}
137+
138+
log.Debug("Asking chatGPT question...")
139+
answer, err = ai.Question(files, chatPrompt, conf)
140+
if err != nil {
141+
log.Errorf("Error asking question: %s", err)
142+
os.Exit(1)
143+
}
97144
} else {
145+
log.Debug("Getting file contents...")
98146
fileName = repoPath
99-
}
100-
101-
fmt.Println("Asking question about " + fileName + "...")
147+
content, err := utils.LoadFile(fileName)
148+
if err != nil {
149+
log.Errorf("Error loading file: %s", err)
150+
os.Exit(1)
151+
}
102152

103-
content, err := utils.LoadFile(fileName)
104-
if err != nil {
105-
log.Errorf("Error loading file: %s", err)
106-
os.Exit(1)
107-
}
153+
log.Debug("Calculating tokens and constructing file...")
154+
tokens, err := calc.PreciseTokens(content)
155+
if err != nil {
156+
log.Errorf("Error calculating tokens: %s", err)
157+
os.Exit(1)
158+
}
108159

109-
resp, err := ai.Question(fileName, content, chatPrompt, conf)
160+
files := []prompt.GitFile{
161+
{
162+
Path: fileName,
163+
Contents: content,
164+
Tokens: int64(tokens),
165+
},
166+
}
110167

111-
if err != nil {
112-
log.Errorf("Error asking question: %s", err)
113-
os.Exit(1)
168+
log.Debug("Asking chatGPT question...")
169+
answer, err = ai.Question(files, chatPrompt, conf)
170+
if err != nil {
171+
log.Errorf("Error asking question: %s", err)
172+
os.Exit(1)
173+
}
114174
}
115175

116-
fmt.Println("Answer:", resp)
176+
fmt.Println("Answer:", answer)
117177
},
118178
}
119179

@@ -122,4 +182,5 @@ func init() {
122182
askCmd.Flags().StringVarP(&chatPrompt, "question", "q", "", "The question to ask")
123183
askCmd.Flags().BoolVarP(&ignoreGitignore, "ignore-gitignore", "g", false, "ignore .gitignore file")
124184
askCmd.Flags().StringVarP(&ignoreFilePath, "ignore", "n", "", "path to .gptignore file")
185+
askCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
125186
}

cmd/cmd.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"os"
99

10+
l "github.com/charmbracelet/log"
1011
"github.com/spf13/cobra"
1112

1213
"github.com/chand1012/ottodocs/pkg/ai"
@@ -20,6 +21,11 @@ var cmdCmd = &cobra.Command{
2021
Short: "Have ChatGPT suggest a command to run next",
2122
Long: `Have ChatGPT suggest a command to run next. This command will use your shell history to suggest a command to run next.
2223
This command is only supported on MacOS and Linux using Bash or Zsh. Windows and other shells coming soon!`,
24+
PreRun: func(cmd *cobra.Command, args []string) {
25+
if verbose {
26+
log.SetLevel(l.DebugLevel)
27+
}
28+
},
2329
Run: func(cmd *cobra.Command, args []string) {
2430
conf, err := config.Load()
2531
if err != nil || conf.APIKey == "" {
@@ -34,16 +40,15 @@ This command is only supported on MacOS and Linux using Bash or Zsh. Windows and
3440
}
3541

3642
log.Info("Thinking....")
37-
43+
log.Debug("Getting shell history...")
3844
history, err := shell.GetHistory(100)
3945
if err != nil {
40-
log.Error("This command is only supported on MacOS and Linux using Bash or Zsh. Windows and other shells coming soon!")
46+
log.Warn("This command is only supported on MacOS and Linux using Bash or Zsh. Windows and other shells coming soon!")
4147
log.Error(err)
4248
os.Exit(1)
4349
}
4450

45-
// fmt.Println("History:", history)
46-
51+
log.Debug("Asking ChatGPT for a command...")
4752
resp, err := ai.CmdQuestion(history, chatPrompt, conf)
4853

4954
if err != nil {
@@ -59,4 +64,5 @@ func init() {
5964
RootCmd.AddCommand(cmdCmd)
6065

6166
cmdCmd.Flags().StringVarP(&chatPrompt, "question", "q", "", "The prompt to use for the chat session")
67+
cmdCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
6268
}

cmd/commit.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/chand1012/ottodocs/pkg/ai"
1212
"github.com/chand1012/ottodocs/pkg/config"
1313
"github.com/chand1012/ottodocs/pkg/git"
14+
l "github.com/charmbracelet/log"
1415
"github.com/spf13/cobra"
1516
)
1617

@@ -19,6 +20,11 @@ var commitCmd = &cobra.Command{
1920
Use: "commit",
2021
Short: "Generates a commit message from the git diff",
2122
Long: `Uses the git diff to generate a commit message. Requires Git to be installed on the system.`,
23+
PreRun: func(cmd *cobra.Command, args []string) {
24+
if verbose {
25+
log.SetLevel(l.DebugLevel)
26+
}
27+
},
2228
Run: func(cmd *cobra.Command, args []string) {
2329
conf, err := config.Load()
2430
if err != nil || conf.APIKey == "" {
@@ -29,7 +35,7 @@ var commitCmd = &cobra.Command{
2935
}
3036

3137
log.Info("Generating commit message...")
32-
38+
log.Debug("Getting git diff...")
3339
c := exec.Command("git", "diff")
3440
diffBytes, err := c.Output()
3541
if err != nil {
@@ -38,7 +44,7 @@ var commitCmd = &cobra.Command{
3844
}
3945

4046
diff := string(diffBytes)
41-
47+
log.Debug("Sending diff to ChatGPT...")
4248
msg, err := ai.CommitMessage(diff, conventional, conf)
4349
if err != nil {
4450
log.Error(err)
@@ -86,4 +92,5 @@ func init() {
8692
commitCmd.Flags().BoolVarP(&plain, "plain", "p", false, "no output formatting")
8793
commitCmd.Flags().BoolVarP(&auto, "auto", "a", false, "automatically add all and commit with the generated message")
8894
commitCmd.Flags().BoolVar(&push, "push", false, "automatically push to the current branch")
95+
commitCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
8996
}

cmd/docs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,22 @@ search for files in the directory and document them. If a single file is specifi
5757
os.Exit(1)
5858
}
5959

60+
log.Debug("Loading file info...")
6061
info, err := os.Stat(repoPath)
6162
if err != nil {
6263
log.Errorf("Error getting file info: %s", err)
6364
os.Exit(1)
6465
}
6566

6667
if info.IsDir() {
68+
log.Debug("Getting repo...")
6769
repo, err := git.GetRepo(repoPath, ignoreFilePath, ignoreGitignore)
6870
if err != nil {
6971
log.Errorf("Error: %s", err)
7072
os.Exit(1)
7173
}
7274

75+
log.Debug("Documenting repo...")
7376
for _, file := range repo.Files {
7477
var contents string
7578

@@ -83,6 +86,7 @@ search for files in the directory and document them. If a single file is specifi
8386
chatPrompt = "Write documentation for the following code snippet. The file name is" + file.Path + ":"
8487
}
8588

89+
log.Debugf("Loading file %s", path)
8690
fileContents, err := utils.LoadFile(path)
8791
if err != nil {
8892
log.Warnf("Error loading file %s: %s", path, err)

cmd/root.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,5 @@ func Execute() {
2929
}
3030

3131
func init() {
32-
// Here you will define your flags and configuration settings.
33-
// Cobra supports persistent flags, which, if defined here,
34-
// will be global for your application.
35-
36-
// RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ottodocs.yaml)")
37-
38-
// Cobra also supports local flags, which will only run
39-
// when this action is called directly.
40-
// RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
32+
// RootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
4133
}

cmd/vars.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
l "github.com/charmbracelet/log"
77
)
88

9+
var verbose bool
10+
911
var repoPath string
1012
var preambleFile string
1113
var outputFile string

pkg/ai/question.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
package ai
22

33
import (
4-
"strings"
4+
"github.com/chand1012/git2gpt/prompt"
55

6+
"github.com/chand1012/ottodocs/pkg/calc"
67
"github.com/chand1012/ottodocs/pkg/config"
78
"github.com/chand1012/ottodocs/pkg/constants"
89
)
910

10-
func Question(filePath, fileContent, chatPrompt string, conf *config.Config) (string, error) {
11-
question := "File Name: " + filePath + "\nQuestion: " + chatPrompt + "\n\n" + strings.TrimRight(string(fileContent), " \n") + "\nAnswer:"
11+
func Question(files []prompt.GitFile, chatPrompt string, conf *config.Config) (string, error) {
12+
question := "\nGiven the context of the above code, answer the following question.\nQuestion: " + chatPrompt + "\nAnswer:"
13+
t, err := calc.PreciseTokens(question)
14+
if err != nil {
15+
return "", err
16+
}
1217

13-
return request(constants.QUESTION_PROMPT, question, conf)
18+
tokens := int64(t)
19+
20+
var prompt string
21+
for _, file := range files {
22+
if file.Tokens+tokens > int64(calc.GetMaxTokens(conf.Model)) {
23+
break
24+
}
25+
prompt += "Filename: " + file.Path + "\n" + file.Contents + "\n"
26+
}
27+
28+
return request(constants.QUESTION_PROMPT, prompt+question, conf)
1429
}

0 commit comments

Comments
 (0)