/** * RemoteBrain - rbrain * * This file is licensed under the Affero General Public License version 3 or * later. See the COPYING file. * * @author Paolo Lulli * @copyright Paolo Lulli 2026 */ package main import ( "bufio" "database/sql" "errors" "fmt" "os" "rbrain/internal/config" "rbrain/internal/encoding" "rbrain/internal/queries" "rbrain/internal/service" "rbrain/internal/tlsclient" "strings" "time" ) func main() { configPath := os.Getenv("HOME") + "/.config/rbrain/config.json" if _, err := os.Stat(configPath); errors.Is(err, os.ErrNotExist) { fmt.Printf("Config file %s doesn't exist\n", configPath) os.Exit(1) } cfg := config.GetClientConfig(configPath) var c = tlsclient.RBrain{Config: cfg} model := cfg.Model if len(os.Args) > 1 { model = os.Args[1] } db, err := sql.Open("sqlite", cfg.DbFile) if err != nil { fmt.Fprintf(os.Stderr, "Cannot open database: %v\n", err) os.Exit(1) } defer db.Close() if err := queries.InitSchema(db); err != nil { fmt.Fprintf(os.Stderr, "Cannot initialise schema: %v\n", err) os.Exit(1) } fmt.Printf("\nRemote Brain\n") fmt.Printf(" model : %s\n", model) fmt.Printf(" database : %s\n", cfg.DbFile) fmt.Printf("%s\n\n", strings.Repeat("─", 64)) scanner := bufio.NewScanner(os.Stdin) ch := make(chan service.Result, 1) for { fmt.Print("[Request]: ") if !scanner.Scan() { break } input := strings.TrimSpace(scanner.Text()) if input == "" { continue } switch { case input == ":quit" || input == ":exit" || input == ":q": fmt.Println("Exiting") return case input == ":history": printHistory(db) continue case strings.HasPrefix(input, ":model "): model = strings.TrimPrefix(input, ":model ") fmt.Printf("Model switched to: %s\n\n", model) continue } fmt.Print(" [Bot]: Processing...") c.ProcessMessage(db, input, model, ch) res := <-ch fmt.Print("\r [Bot]: ") if res.Err != nil { fmt.Printf("Error: %v\n\n", res.Err) } else { fmt.Printf("%s\n\n", strings.TrimSpace(res.Text)) } } if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "Scanner: %v\n", err) } } func printHistory(db *sql.DB) { rows, err := queries.GetRequestsHistory(db) if err != nil { fmt.Printf("History error: %v\n", err) return } fmt.Printf("\n%s\n", strings.Repeat("─", 64)) fmt.Println("Last conversations (oldest first)") fmt.Printf("%s\n", strings.Repeat("─", 64)) defer rows.Close() for rows.Next() { var message, response, createdAt string if err := rows.Scan(&message, &response, &createdAt); err != nil { fmt.Printf("History error: %v\n", err) return } if t, err := time.Parse("2006-01-02 15:04:05", createdAt); err == nil { createdAt = t.Format("Jan 02 2006 15:04:05") } fmt.Printf("\ntime: %s\n", createdAt) fmt.Printf("query: %s\n", encoding.DecodeB64(message)) fmt.Printf("response %s\n", encoding.DecodeB64(response)) } fmt.Printf("%s\n", strings.Repeat("─", 64)) }