# Axis - Agent Documentation > Quick reference for AI agents integrating with the Axis onchain agent CLI. --- ## TL;DR for Agents | What | Value | |------|-------| | **Type** | CLI + HTTP API | | **Language** | Shell (CLI), REST (HTTP API) | | **Auth Required** | Yes - Cartridge Controller session or private key | | **Rate Limit** | None documented (onchain gas limits apply) | | **Install** | `curl -fsSL https://github.com/bibliothecadao/eternum/releases/latest/download/install-axis.sh \| bash` | | **Runtime Dir** | `~/.eternum-agent` | | **Source** | https://github.com/bibliothecadao/eternum | | **Docs** | https://docs.realms.world/development/axis/overview | --- ## What Axis Does Axis is an onchain agent CLI for the Eternum game. It: - Discovers active game worlds across slot, sepolia, and mainnet - Authenticates via Cartridge Controller - Runs an LLM-driven tick loop observing game state - Executes on-chain actions generated from contract ABIs - Persists agent memory and strategy per world --- ## Quick Start ### Interactive Mode (TUI) ```bash # Install curl -fsSL https://github.com/bibliothecadao/eternum/releases/latest/download/install-axis.sh | bash # Configure echo "ANTHROPIC_API_KEY=sk-ant-..." >> ~/.eternum-agent/.env # Run (opens browser for auth, starts agent) axis ``` ### Headless Mode (VPS/Orchestration) ```bash # Configure echo "ANTHROPIC_API_KEY=sk-ant-..." >> ~/.eternum-agent/.env # Authenticate axis auth my-world --method=password --username=me --password=secret # Run axis run --headless --world=my-world --api-port=3000 ``` --- ## Authentication ``` Method: Cartridge Controller session OR private key Config files: ~/.eternum-agent/.cartridge//session.json Session duration: 7 days ``` ### Password Auth (Recommended for Headless) ```bash axis auth {world} --method=password --username={user} --password={pass} ``` ### Browser Auth (Interactive) ```bash # Generate auth URL axis auth {world} # Complete with redirect URL axis auth {world} --redirect-url="http://localhost:PORT/callback?startapp=..." ``` ### Private Key Auth (Bypass Cartridge) ```bash PRIVATE_KEY=0x... ACCOUNT_ADDRESS=0x... axis run --headless --world=my-world --auth=privatekey ``` --- ## HTTP API Endpoints Enable with `--api-port={port}` in headless mode. ### POST /prompt Queue a prompt for the agent to process. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `content` | string | yes | Prompt text for the agent | **Request:** ```json { "content": "Build a farm at your main realm" } ``` **Response (200 OK):** ```json { "status": "queued" } ``` --- ### GET /status Get current agent status. **Response (200 OK):** ```json { "world": "my-world", "loopEnabled": true, "tickIntervalMs": 60000, "lastTick": "2026-03-05T12:00:00Z" } ``` --- ### GET /state Get world state snapshot. **Response (200 OK):** ```json { "world": "my-world", "entities": [...], "resources": {...} } ``` --- ### GET /events Server-sent events stream. **Response:** `text/event-stream` --- ### POST /config Update runtime configuration. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `changes` | array | yes | Array of {path, value} objects | **Request:** ```json { "changes": [ {"path": "tickIntervalMs", "value": 30000} ] } ``` **Response (200 OK):** ```json { "status": "updated" } ``` **Configurable Paths:** - `tickIntervalMs` - Tick interval in ms - `loopEnabled` - Enable/disable auto-tick - `modelProvider` - LLM provider - `modelId` - Model identifier --- ### POST /shutdown Graceful shutdown. **Response (200 OK):** ```json { "status": "shutting_down" } ``` --- ## CLI Commands Reference | Command | Description | |---------|-------------| | `axis` | Run in TUI mode | | `axis run --headless --world={name}` | Run in headless mode | | `axis worlds` | List discovered worlds | | `axis auth {world}` | Generate auth URL | | `axis auth {world} --method=password` | Password auth | | `axis auth {world} --status` | Check session status | | `axis auth --all --status --json` | Check all worlds status | | `axis doctor` | Validate configuration | | `axis --version` | Print version | | `axis --help` | Print usage | --- ## Stdin Control (Headless) Send JSON objects line-by-line when `--stdin` is set: ```jsonl {"type":"prompt","content":"Scout north"} {"type":"config","changes":[{"path":"tickIntervalMs","value":45000}]} {"type":"shutdown"} ``` --- ## NDJSON Output Events Headless mode emits newline-delimited JSON to stdout: | Event Type | Verbosity Level | Description | |------------|-----------------|-------------| | `startup` | decisions | Agent started | | `session` | quiet | Session state change | | `decision` | decisions | Agent made a decision | | `action` | actions | On-chain action executed | | `prompt` | decisions | Prompt received/processed | | `heartbeat` | decisions | Tick heartbeat | | `config` | decisions | Configuration change | | `error` | quiet | Error occurred | | `shutdown` | quiet | Agent shutting down | | `tick` | all | Individual tick event | **Verbosity Levels (cumulative):** - `quiet`: error, session, shutdown - `actions`: quiet + action - `decisions`: actions + decision, heartbeat, prompt, startup, config - `all`: decisions + tick --- ## Common Patterns ### Pattern 1: Fleet Orchestration When to use: Running multiple agents across worlds ```bash # Auth all worlds axis auth --all --method=password --username=me --password=secret --json > /tmp/auth.json # Start agents on random ports for world in $(jq -r '.[].world' /tmp/auth.json); do axis run --headless --world="$world" --api-port=$((3000 + RANDOM % 1000)) & done ``` ### Pattern 2: Remote Control via HTTP When to use: Orchestrator needs to send commands ```bash # Send prompt curl -X POST http://127.0.0.1:3000/prompt \ -H 'Content-Type: application/json' \ -d '{"content":"Build a farm at your main realm"}' # Update config curl -X POST http://127.0.0.1:3000/config \ -H 'Content-Type: application/json' \ -d '{"changes":[{"path":"tickIntervalMs","value":30000}]}' ``` ### Pattern 3: VPS First-Time Setup When to use: Setting up on headless VPS without browser ```bash # Generate QR (saved to ~/.eternum-agent/.cartridge/{world}/auth-qr.png) axis auth my-world # Scan QR on mobile, approve on Cartridge # Paste redirect URL axis auth my-world --redirect-url="http://localhost:PORT/callback?startapp=..." ``` --- ## Agent-Specific Notes - **Idempotency:** POST /prompt queues prompts; multiple identical prompts will queue multiple times - **Retry Logic:** On auth failure, re-run `axis auth`; sessions expire after 7 days - **Polling:** Use GET /events (SSE) for real-time updates instead of polling /status - **State Persistence:** Agent memory stored in `~/.eternum-agent/data/{world}/` --- ## Errors | Error | Meaning | Action | |-------|---------|--------| | `No worlds discovered` | Network unreachable or wrong API base | Check network, verify CARTRIDGE_API_BASE | | `--world is required for headless mode` | Missing world flag | Add `--world={name}` flag | | `Auth remains pending` | Browser approval incomplete | Complete `axis auth --redirect-url=...` | | `Password auth fails` | Wrong credentials | Verify username/password | | `Session expired` | Session > 7 days old | Re-run `axis auth` | See [error-codes.yaml](./error-codes.yaml) for programmatic error handling. --- ## Version Compatibility | Version | Status | Notes | |---------|--------|-------| | v0.1.x | Current | Initial release | --- ## File Structure ``` ~/.eternum-agent/ ├── .env # Global config (API keys) ├── data/ │ └── {world}/ │ ├── soul.md # Agent persona │ ├── HEARTBEAT.md # Periodic tasks │ └── tasks/ # Strategy files └── .cartridge/ └── {world}/ ├── session.json # Controller session ├── profile.json # World profile ├── manifest.json # Contract manifest ├── policy.json # Session policies ├── auth.json # Auth metadata └── auth-qr.png # Auth QR code ``` --- *This documentation follows [Agent Documentation Patterns](https://github.com/spiritclawd/agent-docs-patterns)*