obm/LLMs.md
Jezza Hehn 79d08fb63c
Some checks failed
CI / Test (push) Failing after 45s
CI / Build-3 (push) Has been skipped
CI / Build (push) Has been skipped
CI / Build-1 (push) Has been skipped
CI / Build-2 (push) Has been skipped
CI / Build-4 (push) Has been skipped
whitespace adjustment
2026-05-22 19:32:06 -04:00

272 lines
9.6 KiB
Markdown

# LLMs.md — Agent Reference for obm
This file is written for AI agents (LLMs, coding assistants, autonomous agents) who need to understand the `obm` project and work with their human to deploy, configure, or develop it. If you're reading this, you're probably an agent trying to help someone. Here's what you need to know.
---
## What obm Is
`obm` (OpenBoatMobile) is a Go CLI tool that deploys AI agents to cloud infrastructure. It generates Terraform-compatible `.env` files through an interactive walkthrough or a YAML config, validates API credentials against live endpoints, and wraps Terraform lifecycle commands.
Think of it as: "Terraform for AI agents, with a friendly wizard instead of a 94-line `.env` template."
---
## Quick Orientation
| Fact | Value |
|------|-------|
| Language | Go 1.22 |
| Module path | `github.com/openboatmobile/obm` |
| External deps | `gopkg.in/yaml.v3` only |
| Binary type | Static, zero runtime deps |
| Version file | `VERSION` (single line, e.g. `0.1.0`) |
| Current version | 0.1.0 |
| License | MIT |
**Repos:**
- `obm` (this repo) — the Go CLI
- `openboatmobile-ai` — the Terraform configs that `obm` generates `.env` files for
- `openboatmobile` (private) — live deployment with keys, do NOT touch
---
## Package Map
Use this to find what you need:
```
cmd/obm/main.go → Entry point, subcommand routing, build-time version vars
internal/config/ → All configuration types and I/O:
config.go → Config struct, GetValue/SetValue
deployment.go → DeploymentConfig (30+ fields), cost estimation
schema.go → VarDef schema (all Terraform variables), VarGroup enum
dotenv.go → DotEnvFile round-trip parser
dotenv_writer.go → WriteDotEnv — grouped .env output
tfvars.go → WriteTfVars — HCL-format output
yaml.go → YAMLConfig, LoadYAMLConfig, ToDeploymentConfig
internal/deploy/deploy.go → Walkthrough orchestrator (Run, RunFromFile, RunWithConfig)
internal/destroy/destroy.go → Terraform destroy with state parsing
internal/inference/ → Inference provider validation:
client.go → HTTP client, ValidateAPIKey, ValidationResult
inference.go → Provider enum, ProviderConfig, FallbackChain
internal/prompt/prompt.go → Terminal I/O: Select, Confirm, Input, Password, colors
internal/provider/ → Cloud provider abstraction:
provider.go → Provider interface, BaseProvider, Registry
hetzner/hetzner.go → Hetzner Cloud API: token validation, SSH key listing
internal/terraform/terraform.go → Runner: Init, Plan, Apply, Destroy
internal/validation/validation.go → Check interface, Runner, CheckResult, Status enum
```
---
## CLI Commands Your Human Might Ask About
| Command | What it does | When they'd use it |
|---------|-------------|-------------------|
| `obm deploy` | Interactive 8-step walkthrough | First-time setup or redeploy |
| `obm deploy --config deploy.yaml` | Non-interactive from YAML | CI/CD, automation, repeat deploys |
| `obm validate` | Check `.env` + validate API keys | "Did I configure this right?" |
| `obm destroy` | Tear down infrastructure | "I'm done with this server" |
| `obm version` | Print version with commit/build info | Debugging |
---
## Deploy Walkthrough Steps
When your human runs `obm deploy`, they'll go through these in order:
1. **Framework** — Hermes or OpenClaw
2. **Cloud Provider** — Hetzner or DigitalOcean
3. **Provider Token** — API key for their cloud provider (validated live)
4. **SSH Key** — Select from provider or enter manually
5. **Server Config** — Name, location/region, size
6. **Inference Provider** — ZAI, Venice, or OpenRouter (API key validated live)
7. **Tailscale** — Optional VPN (auth key + tailnet)
8. **Discord** — Optional bot integration (token, server ID, user IDs)
After all 8 steps: summary + cost estimate → confirm → `.env` written → optional `terraform init && apply`.
---
## What Your Human Needs Before Deploying
Tell them to have these ready:
1. **Cloud provider account** with API token (Hetzner: console.hetzner.cloud → Security → API Tokens; DO: cloud.digitalocean.com → API)
2. **SSH public key** uploaded to their cloud provider
3. **Inference provider API key** (Venice, OpenRouter, or ZAI)
4. *(Optional)* Tailscale auth key
5. *(Optional)* Discord bot token + server ID
---
## Framework Differences
When your human asks "Hermes or OpenClaw?":
**Hermes Agent** — if they want:
- Discord chat, voice, web search, many integrations
- Python-based, Docker or direct install
- More configurable (gateway, allowed users, auto-threading)
**OpenClaw** — if they want:
- Simpler setup, fewer moving parts
- Node.js-based
- Built-in security (fail2ban, unattended upgrades, swap)
---
## Configuration Files
### `.env` (Terraform input)
All variables prefixed with `TF_VAR_`. Generated by `obm deploy` or `WriteDotEnv()`. This is the primary output of the tool. Groups: PROVIDER, SERVER, SSH, API KEYS, MODEL, DISCORD, TAILSCALE, HERMES-SPECIFIC, OPENCLAW-SPECIFIC, SECURITY, PROJECT.
Special format for SSH keys: `TF_VAR_ssh_key_names='["key-name"]'` — single-quoted shell string containing JSON array.
### `deploy.yaml` (Non-interactive input)
Full schema in `deploy.yaml.example`. Key sections:
```yaml
framework: hermes
provider:
name: hetzner
token: "..."
ssh:
names: ["my-key"]
server:
name: "agent"
location: "ash"
type: "cpx21"
inference:
provider: venice
api_key: "..."
primary_model: "zai-org-glm-5"
tailscale:
enabled: true
auth_key: "..."
discord:
enabled: false
```
---
## Build Commands
```bash
make build # Build for current platform
make test # Test with race detection + coverage
make lint # go vet + gofmt
make cross-compile # All platforms: linux-{amd64,arm64}, darwin-arm64, windows-{amd64,arm64}
make clean # Remove binary + coverage
```
From source without make:
```bash
go build -o obm ./cmd/obm
go test ./...
go vet ./...
```
Version injection at build time:
```bash
go build -ldflags "-s -w -X main.version=$(cat VERSION) -X main.gitCommit=$(git rev-parse --short HEAD) -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" -o obm ./cmd/obm
```
---
## Common Tasks Your Human Might Ask For
### "Help me deploy an agent"
1. Make sure they have API keys ready (see "What Your Human Needs" above)
2. Run `obm deploy`
3. Walk them through the 8 steps if they have questions
4. The cost estimate at the end is approximate — cloud providers may vary
### "Check if my config is valid"
```bash
obm validate
```
This loads `.env`, checks required variables, and validates inference API keys against live endpoints.
### "I want to tear down my server"
```bash
obm destroy
```
It asks for confirmation. It reads `terraform.tfstate` to show what will be destroyed.
### "Set up CI/CD deployment"
1. Create a `deploy.yaml` from `deploy.yaml.example`
2. Store secrets in your CI secrets manager
3. In pipeline: `obm deploy --config deploy.yaml`
### "Add a new cloud provider"
1. Create `internal/provider/<name>/<name>.go` implementing the `Provider` interface
2. Register via `init()`: `provider.Register("<name>", func() provider.Provider { return New() })`
3. Add provider-specific fields to `DeploymentConfig`
4. Update `schema.go` with new `VarGroup` and `VarDef` entries
5. Add step function in `deploy.go`
### "Add a new inference provider"
1. Add `Provider<Name>` constant to `internal/inference/inference.go`
2. Add case to `Info()` method (name, env var, base URL)
3. Add case to `UnmarshalText()` for YAML parsing
4. Add case to `setAuthHeaders()` in `client.go` if auth differs from Bearer token
5. Update `AllProviders()` return slice
---
## Known Limitations
- `obm status` is stubbed — not yet functional
- DigitalOcean provider validation not yet implemented (only Hetzner)
- No resumable deploy — interrupted walkthrough = start over
- No cost preview before the summary step
- `openai` and `anthropic` inference providers listed in schema but not fully implemented in the inference client (only ZAI, Venice, OpenRouter have live validation)
---
## Relationship to Terraform Configs
`obm` generates the `.env` file. The Terraform configs that consume it live in the `openboatmobile-ai` repo. The variable schema in `internal/config/schema.go` must stay in sync with the Terraform variable definitions in `openboatmobile-ai/variables-*.tf`.
If you add a variable to the Terraform configs, you must also add a corresponding `VarDef` to `schema.go`.
---
## Testing Strategy
- Unit tests in each package (`*_test.go`)
- Hetzner provider tested with mock HTTP servers (`WithHTTPClient` + `WithBaseURL` options)
- Inference client tested with mock `/models` endpoints
- Run with: `make test` or `go test -v -race -coverprofile=coverage.out ./...`
---
## File Locations Summary
| File | Purpose |
|------|---------|
| `VERSION` | Single-line semver string |
| `Makefile` | Build, test, lint, cross-compile targets |
| `Dockerfile` | Multi-stage build for containerized obm |
| `deploy.yaml.example` | Full YAML config reference |
| `scripts/install.sh` | `curl \| sh` installer |
| `scripts/release.sh` | Tag + push release automation |
| `.github/workflows/ci.yml` | Test + build on push/PR |
| `.github/workflows/release.yml` | Cross-compile + GitHub Release on tag |
| `CHANGELOG.md` | Version history |
| `CONTRIBUTING.md` | Dev setup, PR checklist, release process |
| `README.md` | User-facing overview (casual tone) |
| `DETAILS.md` | Full technical reference |
| `LLMs.md` | This file — agent-oriented reference |