272 lines
9.6 KiB
Markdown
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 |
|