@@ -17,6 +17,15 @@ const (
17
17
maxFileSize = 10000
18
18
)
19
19
20
+ // ANSI color codes
21
+ const (
22
+ colorReset = "\033 [0m"
23
+ colorCyan = "\033 [36m" // for user input
24
+ colorYellow = "\033 [33m" // for AI responses
25
+ colorRed = "\033 [31m" // for errors
26
+ colorBlue = "\033 [34m" // for system messages
27
+ )
28
+
20
29
type Cmd struct {
21
30
AI string `help:"Name of service"`
22
31
Model string `help:"Name of model to talk to. Most services have multiple options."`
@@ -79,7 +88,7 @@ func (cmd *Cmd) Run() error {
79
88
HistoryLimit : 1000000 ,
80
89
81
90
Stdin : cmd .stdin ,
82
- Stdout : cmd .stdout ,
91
+ Stdout : & colorWriter { w : cmd .stdout , color : colorCyan }, // Color the user input
83
92
Stderr : cmd .stderr ,
84
93
})
85
94
if err != nil {
@@ -129,7 +138,7 @@ func (cmd *Cmd) sendMessages() error {
129
138
Temperature : cmd .Temperature ,
130
139
Messages : cmd .messagesWithinLimit (),
131
140
}
132
- msg , err := cmd .client ().GenerateStream (req , cmd .stdout )
141
+ msg , err := cmd .client ().GenerateStream (req , & colorWriter { w : cmd .stdout , color : colorYellow } )
133
142
if err != nil {
134
143
return err
135
144
}
@@ -231,6 +240,19 @@ func (cmd *Cmd) handleMeta(line string) string {
231
240
}
232
241
case `\quit` , `\exit` , `\q` :
233
242
os .Exit (0 )
243
+ case `\help` , `\?` :
244
+ cmd .sysOut ("Available commands:" )
245
+ cmd .sysOut (" \\ help, \\ ? Show this help message" )
246
+ cmd .sysOut (" \\ reset Reset conversation (keeps system message)" )
247
+ cmd .sysOut (" \\ reset-system Remove system message" )
248
+ cmd .sysOut (" \\ messages Show all messages in the conversation" )
249
+ cmd .sysOut (" \\ config Show current configuration" )
250
+ cmd .sysOut (" \\ set Set a configuration parameter (usage: \\ set <param> <value>)" )
251
+ cmd .sysOut (" \\ file Add file contents to conversation" )
252
+ cmd .sysOut (" \\ system Set or show system message" )
253
+ cmd .sysOut (" \\ context Set context limit in bytes" )
254
+ cmd .sysOut (" \\ << Start multiline input (optional custom terminator)" )
255
+ cmd .sysOut (" \\ quit, \\ exit, \\ q Exit the program" )
234
256
default :
235
257
err = errors .Errorf ("Unknown meta command '%s'" , line )
236
258
}
@@ -326,7 +348,11 @@ func (cmd *Cmd) appendMessage(msg Message) {
326
348
327
349
func (cmd * Cmd ) printMessages () {
328
350
for _ , msg := range cmd .messages {
329
- cmd .out ("%9s: %s" , msg .Role (), msg .Content ())
351
+ if msg .Role () == "user" {
352
+ cmd .out (colorCyan + "%9s: %s" + colorReset , msg .Role (), msg .Content ())
353
+ } else {
354
+ cmd .out (colorYellow + "%9s: %s" + colorReset , msg .Role (), msg .Content ())
355
+ }
330
356
}
331
357
}
332
358
@@ -340,13 +366,17 @@ func (cmd *Cmd) out(format string, a ...any) {
340
366
fmt .Fprintf (cmd .stdout , format + "\n " , a ... )
341
367
}
342
368
369
+ func (cmd * Cmd ) sysOut (format string , a ... any ) {
370
+ fmt .Fprintf (cmd .stdout , colorBlue + format + colorReset + "\n " , a ... )
371
+ }
372
+
343
373
func (cmd * Cmd ) err (err error ) {
344
- fmt .Fprintf (cmd .stderr , err . Error () + " \n " )
374
+ fmt .Fprintf (cmd .stderr , colorRed + "%s" + colorReset + " \n ", err . Error () )
345
375
}
346
376
347
377
// errOut wraps the error and writes it to the user on stderr.
348
378
func (cmd * Cmd ) errOut (err error , format string , a ... any ) {
349
- fmt .Fprintf (cmd .stderr , "%s: %v" , fmt .Sprintf (format , a ... ), err .Error ())
379
+ fmt .Fprintf (cmd .stderr , colorRed + "%s: %v" + colorReset + " \n " , fmt .Sprintf (format , a ... ), err .Error ())
350
380
}
351
381
352
382
// checkConfig ensures the command configuration is valid before proceeding.
@@ -413,3 +443,22 @@ func (cmd *Cmd) readConfigFile() error {
413
443
}
414
444
return nil
415
445
}
446
+
447
+ // colorWriter wraps an io.Writer and adds color codes
448
+ type colorWriter struct {
449
+ w io.Writer
450
+ color string
451
+ }
452
+
453
+ func (cw * colorWriter ) Write (p []byte ) (n int , err error ) {
454
+ // Write the color code, then the content, then reset
455
+ if _ , err := cw .w .Write ([]byte (cw .color )); err != nil {
456
+ return 0 , err
457
+ }
458
+ n , err = cw .w .Write (p )
459
+ if err != nil {
460
+ return n , err
461
+ }
462
+ _ , err = cw .w .Write ([]byte (colorReset ))
463
+ return n , err
464
+ }
0 commit comments