# Faraday: The Hitchhiker's Guide to Command-Line AI

## Building Faraday: A Guide to Crafting Your Command-Line AI Companion

In a universe teeming with digital chaos, Faraday emerges as the improbable hero, a command-line Go application designed to converse with AI services. Much like a towel in the hands of a seasoned hitchhiker, Faraday is indispensable for those navigating the vast expanse of artificial intelligence.

Faraday's charm lies in its simplicity. It takes user prompts and, with the grace of a Vogon poet, communicates with an AI service to deliver responses. The application is configured via a YAML file, ensuring that even the most befuddled of users can set it up without resorting to pan-galactic gargle blasters.

Building Faraday is as straightforward as asking for a cup of tea from the Nutri-Matic machine. With a simple `task build`, you can compile it for your local system. For those with intergalactic ambitions, `task release` allows you to build it for multiple platforms, ensuring compatibility across the galaxy.

### Technical Details: Navigating the Code Cosmos

Faraday's core functionality revolves around its ability to parse command-line arguments and interact with an AI service. The main function processes user input, checking for context files using the `@file` syntax. It then constructs a request body, including user prompts and optional context, and sends it to the AI service via HTTP POST.

The application utilizes Go's `flag` package for argument parsing and `yaml.v3` for configuration management. It gracefully handles errors, ensuring that even the most catastrophic of failures are met with a polite message rather than a Vogon-like tirade.

### File-by-File Guide to Building Faraday

**main.go:** This is the heart of Faraday. It initializes configuration settings from `config.yaml`, parses command-line arguments, and communicates with the AI service.

Go

```go
func init() {
  exePath, err := os.Executable()
  if err != nil {
    fmt.Printf("Error getting executable path: %v\n", err)
    os.Exit(1)
  }
  configFilePath := filepath.Join(filepath.Dir(exePath), "config.yaml")
  configFile, err := os.Open(configFilePath)
  if err != nil {
    fmt.Printf("Error opening config file: %v\n", err)
    os.Exit(1)
  }
  defer configFile.Close()

  yamlDecoder := yaml.NewDecoder(configFile)
  err = yamlDecoder.Decode(&config)
  if err != nil {
    fmt.Printf("Error decoding config file: %v\n", err)
    os.Exit(1)
  }
}

func callAIService(prompt string, contextFilePath string) (string, error) {
  // ... function implementation ...
}
```

The `callAIService()` function constructs and sends HTTP requests, handling responses with elegance.

Go

```go
func callAIService(prompt string, contextFilePath string) (string, error) {
  // ... function implementation ...
}
```

**config.yaml:** This file is crucial for configuration, containing the API URL and key. It should reside in the same directory as the executable, ensuring seamless communication with the AI service.

YAML

```yaml
api:
  url: "https://api.example.com"
  key: "your-api-key"
```

**Build Process:** Ensure Go 1.23 or later is installed, along with [Task](https://taskfile.dev/) for task management. Use `task build` to compile locally, or `task release` for cross-platform builds:

```bash
task build
```

```bash
task release
```

In conclusion, Faraday is a delightful tool for those seeking to interact with AI services from the comfort of their command line. Its ease of use and configuration make it a must-have for any digital hitchhiker.

For the source and pre-built binaries, check out my repository at [https://github.com/jleski/faraday](https://github.com/jleski/faraday)
