-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcopilot.go
More file actions
151 lines (123 loc) · 3.82 KB
/
copilot.go
File metadata and controls
151 lines (123 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"fmt"
"time"
"github.com/fatih/color"
"github.com/getlantern/systray"
"github.com/getlantern/systray/example/icon"
"github.com/ncruces/zenity"
"github.com/spf13/cobra"
)
// WriterCmd represents the writer command
var CoPilotCmd = &cobra.Command{
Use: "assist [text]",
Aliases: []string{"a", "copilot", "assistant"},
Short: "Help user with anything on his/her screen.",
Long: `Help user with anything on his/her screen.`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
if textToSpeech {
RunTts(args[0])
return nil
}
}
// Indicate processing
processingMsg := color.New(color.FgYellow).PrintFunc()
processingMsg("Starting Gema tray application...\n")
systray.Run(onReady, onExit)
return nil
},
}
var textToSpeech bool = false
func init() {
CoPilotCmd.Flags().BoolVarP(&textToSpeech, "tts", "t", false, "Clean output for text-to-speech")
}
func onReady() {
fmt.Println("Initializing system tray...")
systray.SetIcon(icon.Data)
systray.SetTitle("Gema")
mHelp := systray.AddMenuItem("Help", "Take Screensot and and audio.")
fmt.Println("Gema is now running in your system tray")
// Listen for clicks on the help button
go func() {
for {
<-mHelp.ClickedCh
fmt.Println("Help button clicked, launching Copilot...")
RunCopilot()
}
}()
}
func onExit() {
fmt.Println("Exiting Gema...")
// clean up here
}
func RunCopilot() {
fmt.Println("--------------------------------------------------")
fmt.Printf("[%s] Starting Gema Assistant\n", time.Now().Format("15:04:05"))
fmt.Println("[INFO] Displaying input dialog...")
// Ask the user for their question with a centered dialog
userQuery, err := zenity.Entry(
"What would you like help with?",
zenity.Title("Gema Assistant"),
zenity.Width(400),
)
if err != nil {
// User canceled or there was an error
fmt.Printf("[ERROR] Dialog error: %v\n", err)
return
}
// If the user didn't enter anything, return early
if userQuery == "" {
fmt.Println("[INFO] No query provided, canceling request")
return
}
fmt.Println("[INFO] Taking screenshot...")
imgBytes, err := Screenshot()
if err != nil {
fmt.Printf("[ERROR] Failed to capture screenshot: %v\n", err)
} else {
fmt.Printf("[INFO] Screenshot captured successfully (%d bytes)\n", len(imgBytes))
}
fmt.Println("[INFO] Sending query to AI service...")
aiResp := AskQuery(userQuery, [][]byte{imgBytes})
fmt.Println("====================================")
fmt.Printf("[%s] QUERY: %s\n", time.Now().Format("15:04:05"), userQuery)
fmt.Println("====================================")
fmt.Println("[RESPONSE]")
fmt.Println(aiResp.Response)
fmt.Println("====================================")
fmt.Println("[INFO] Copying response to clipboard...")
err = PutTextOnClipboard(aiResp.Response)
if err != nil {
fmt.Printf("[ERROR] Failed to copy to clipboard: %v\n", err)
} else {
fmt.Println("[INFO] Response copied to clipboard")
}
fmt.Println("[INFO] Converting response to speech...")
// Create a channel to signal speech to stop
stopSpeech := make(chan struct{})
// Start speech in a goroutine
go func() {
SpeakMessage(aiResp.Response, stopSpeech)
}()
// Monitor CLI input in parallel
go func() {
fmt.Println("[INFO] Press any key to stop speech...")
var input string
fmt.Scanln(&input) // Wait for Enter, but any input will work
close(stopSpeech) // Signal to stop the speech
fmt.Println("[INFO] Speech stopped by user input")
}()
// Wait for speech to complete or be stopped
<-stopSpeech
fmt.Printf("[%s] Gema Assistant completed\n", time.Now().Format("15:04:05"))
fmt.Println("--------------------------------------------------")
}
func RunTts(query string) {
if !textToSpeech {
return
}
imgBytes, _ := Screenshot()
genaiResponse := AskQuery(query, [][]byte{imgBytes})
fmt.Println(genaiResponse.Response)
}