Skip to content

Instantly share code, notes, and snippets.

@Catorpilor
Created March 5, 2026 06:53
Show Gist options
  • Select an option

  • Save Catorpilor/faaf2bda29a01fa16f891579a54e71a9 to your computer and use it in GitHub Desktop.

Select an option

Save Catorpilor/faaf2bda29a01fa16f891579a54e71a9 to your computer and use it in GitHub Desktop.
Axis CLI - Agent-Readable Documentation (for AI agents integrating with Eternum)
# Axis CLI - Agent Quick Reference
# Version: 0.1.0 (Agent Docs)
# Source: https://docs.realms.world/development/axis/overview
api:
type: CLI + HTTP
cli_binary: axis
install: curl -fsSL https://github.com/bibliothecadao/eternum/releases/latest/download/install-axis.sh | bash
http_base_url: http://127.0.0.1:{api_port}
auth: Cartridge Controller session or private key
runtime_dir: ~/.eternum-agent
# ============================================
# CLI COMMANDS
# ============================================
cli_commands:
# --- Core Commands ---
- name: run_tui
command: axis
description: Run agent in interactive TUI mode
flags: []
- name: run_headless
command: axis run --headless --world={world} --api-port={port}
description: Run agent in headless mode (VPS/orchestrators)
flags:
- name: --headless
required: true
description: Disable TUI, emit NDJSON to stdout
- name: --world
required: true
type: string
description: Target world name
- name: --api-port
required: false
type: integer
description: Enable HTTP API on specified port
- name: --api-host
required: false
type: string
default: "127.0.0.1"
description: API bind host
- name: --stdin
required: false
type: boolean
description: Enable stdin command stream
- name: --verbosity
required: false
type: enum
values: [quiet, actions, decisions, all]
default: decisions
description: Output filter level
- name: --auth
required: false
type: enum
values: [session, privatekey]
default: session
description: Authentication strategy
- name: --json
required: false
type: boolean
description: JSON output for command responses
# --- World Discovery ---
- name: list_worlds
command: axis worlds
description: List discovered active worlds
output: List of worlds with network, status
# --- Authentication ---
- name: auth_password
command: axis auth {world} --method=password --username={user} --password={pass}
description: Authenticate with Cartridge password (headless)
flags:
- name: --method
value: password
description: Use password authentication
- name: --username
required: true
type: string
- name: --password
required: true
type: string
- name: auth_browser
command: axis auth {world}
description: Generate browser auth URL (interactive)
output: Auth URL and QR code path
- name: auth_redirect
command: axis auth {world} --redirect-url={url}
description: Complete browser auth with redirect URL
flags:
- name: --redirect-url
required: true
type: string
description: Redirect URL from Cartridge callback
- name: auth_session_data
command: axis auth {world} --session-data={base64}
description: Complete auth with raw session data
flags:
- name: --session-data
required: true
type: string
description: Base64-encoded session data
- name: auth_callback_server
command: axis auth {world} --callback-url={url}
description: Start callback server for public VPS auth
flags:
- name: --callback-url
required: true
type: string
description: Public callback endpoint URL
- name: auth_all
command: axis auth --all --method=password --username={user} --password={pass} --json
description: Authenticate all discovered worlds
flags:
- name: --all
required: true
description: Target all worlds
- name: --json
required: false
description: Output as JSON
- name: auth_status
command: axis auth {world} --status
description: Check session status for a world
- name: auth_status_all
command: axis auth --all --status --json
description: Check session status for all worlds
# --- Diagnostics ---
- name: doctor
command: axis doctor
description: Validate configuration and diagnose issues
- name: version
command: axis --version
description: Print version
- name: help
command: axis --help
description: Print usage
# --- Initialization ---
- name: init
command: axis init {world}
description: Manually seed runtime directories (optional - auto-created)
# ============================================
# HTTP API (Headless Mode)
# ============================================
http_endpoints:
- name: prompt
method: POST
path: /prompt
description: Queue a prompt for the agent to process
request_body:
content:
type: string
required: true
description: Prompt text for the agent
response:
200:
description: Prompt queued successfully
- name: status
method: GET
path: /status
description: Get agent status
response:
200:
description: Current agent state
- name: state
method: GET
path: /state
description: Get world state snapshot
response:
200:
description: Current world state
- name: events
method: GET
path: /events
description: SSE event stream
response:
200:
content_type: text/event-stream
description: Server-sent events stream
- name: config
method: POST
path: /config
description: Update runtime configuration
request_body:
changes:
type: array
items:
path:
type: string
description: Config path (e.g., tickIntervalMs)
value:
type: any
description: New value
response:
200:
description: Config updated
- name: shutdown
method: POST
path: /shutdown
description: Graceful shutdown
response:
200:
description: Shutdown initiated
- name: auth_callback
method: GET
path: /auth/callback
description: Cartridge callback endpoint
- name: auth_callback_post
method: POST
path: /auth/callback
description: Cartridge callback endpoint (POST variant)
# ============================================
# STDIN COMMANDS (Headless Mode)
# ============================================
stdin_commands:
- type: prompt
description: Send a prompt to the agent
schema:
type: object
properties:
type:
const: prompt
content:
type: string
example: '{"type":"prompt","content":"Scout north"}'
- type: config
description: Update runtime configuration
schema:
type: object
properties:
type:
const: config
changes:
type: array
items:
type: object
properties:
path:
type: string
value: {}
example: '{"type":"config","changes":[{"path":"tickIntervalMs","value":45000}]}'
- type: shutdown
description: Request graceful shutdown
schema:
type: object
properties:
type:
const: shutdown
example: '{"type":"shutdown"}'
# ============================================
# NDJSON EVENT TYPES (Headless Output)
# ============================================
event_types:
- type: startup
verbosity: decisions
description: Agent started
- type: session
verbosity: quiet
description: Session state change
- type: decision
verbosity: decisions
description: Agent made a decision
- type: action
verbosity: actions
description: On-chain action executed
- type: prompt
verbosity: decisions
description: Prompt received/processed
- type: heartbeat
verbosity: decisions
description: Tick heartbeat
- type: config
verbosity: decisions
description: Configuration change
- type: error
verbosity: quiet
description: Error occurred
- type: shutdown
verbosity: quiet
description: Agent shutting down
- type: tick
verbosity: all
description: Individual tick event
# ============================================
# ENVIRONMENT VARIABLES
# ============================================
environment:
required:
- name: ANTHROPIC_API_KEY
description: API key for Anthropic provider
when: MODEL_PROVIDER=anthropic (default)
- name: OPENAI_API_KEY
description: API key for OpenAI provider
when: MODEL_PROVIDER=openai
optional:
- name: MODEL_PROVIDER
default: anthropic
values: [anthropic, openai, openrouter, google]
description: LLM provider
- name: MODEL_ID
default: claude-sonnet-4-5-20250929
description: Model identifier
- name: CHAIN
default: slot
description: Chain selection
- name: SLOT_NAME
description: Auto-select discovered world
- name: TICK_INTERVAL_MS
default: 60000
description: Tick interval in milliseconds
- name: LOOP_ENABLED
default: true
description: Auto-start loop on launch
- name: ETERNUM_AGENT_HOME
default: ~/.eternum-agent
description: Runtime root directory
- name: DATA_DIR
default: $ETERNUM_AGENT_HOME/data
description: Agent data root
- name: SESSION_BASE_PATH
default: $ETERNUM_AGENT_HOME/.cartridge
description: Session/artifact root
advanced:
- name: RPC_URL
description: Manual RPC URL override (skip discovery)
- name: TORII_URL
description: Manual Torii URL override
- name: WORLD_ADDRESS
description: Manual world address override
- name: PRIVATE_KEY
description: Private key for direct auth (no Cartridge)
- name: ACCOUNT_ADDRESS
description: Account address for private key auth
- name: CARTRIDGE_API_BASE
description: Factory/discovery API base override

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)

# 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)

# 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/<world>/session.json
Session duration: 7 days

Password Auth (Recommended for Headless)

axis auth {world} --method=password --username={user} --password={pass}

Browser Auth (Interactive)

# 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)

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:

{
  "content": "Build a farm at your main realm"
}

Response (200 OK):

{
  "status": "queued"
}

GET /status

Get current agent status.

Response (200 OK):

{
  "world": "my-world",
  "loopEnabled": true,
  "tickIntervalMs": 60000,
  "lastTick": "2026-03-05T12:00:00Z"
}

GET /state

Get world state snapshot.

Response (200 OK):

{
  "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:

{
  "changes": [
    {"path": "tickIntervalMs", "value": 30000}
  ]
}

Response (200 OK):

{
  "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):

{
  "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:

{"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

# 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

# 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

# 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 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

# Example: Password authentication for headless mode
name: Authenticate with password
command: axis auth
description: Authenticate to a world using Cartridge password credentials
# Single world authentication
single_world:
command: axis auth my-world --method=password --username=myuser --password=mypass
output_success: |
✓ Authenticated to my-world
Session expires: 2026-03-12T06:50:00Z
output_error: |
✗ Authentication failed: Invalid credentials
Ensure your account has a password credential on Cartridge
# All worlds authentication
all_worlds:
command: axis auth --all --method=password --username=myuser --password=mypass --json
output_success:
- world: world-alpha
status: authenticated
expires: "2026-03-12T06:50:00Z"
- world: world-beta
status: authenticated
expires: "2026-03-12T06:50:00Z"
- world: world-gamma
status: error
error: "No session policies available"
# Check status after auth
check_status:
command: axis auth my-world --status
output:
world: my-world
status: authenticated
expires: "2026-03-12T06:50:00Z"
policies: 12
# Example: Running Axis in headless mode
name: Run in headless mode
command: axis run --headless
description: Start agent for VPS/orchestration with NDJSON output
# Basic headless startup
basic:
command: axis run --headless --world=my-world
output_stream: |
{"type":"startup","world":"my-world","timestamp":"2026-03-05T06:50:00Z"}
{"type":"session","status":"authenticated","expires":"2026-03-12T06:50:00Z"}
{"type":"config","tickIntervalMs":60000,"loopEnabled":true}
{"type":"heartbeat","tick":1,"timestamp":"2026-03-05T06:51:00Z"}
{"type":"decision","action":"scout","target":"north","tick":1}
{"type":"action","txHash":"0x123...","status":"confirmed","tick":1}
# With HTTP API enabled
with_api:
command: axis run --headless --world=my-world --api-port=3000 --stdin
description: Enable HTTP API on port 3000 and stdin command input
output_stream: |
{"type":"startup","world":"my-world","apiPort":3000,"stdin":true}
# With verbosity control
verbosity_levels:
quiet:
command: axis run --headless --world=my-world --verbosity=quiet
description: Only errors, session changes, and shutdown
events: [error, session, shutdown]
actions:
command: axis run --headless --world=my-world --verbosity=actions
description: Quiet + on-chain actions
events: [error, session, shutdown, action]
decisions:
command: axis run --headless --world=my-world --verbosity=decisions
description: Actions + decisions, heartbeats, prompts (default)
events: [error, session, shutdown, action, decision, heartbeat, prompt, startup, config]
all:
command: axis run --headless --world=my-world --verbosity=all
description: Everything including individual ticks
events: [error, session, shutdown, action, decision, heartbeat, prompt, startup, config, tick]
# Using private key auth
privatekey_auth:
command: |
PRIVATE_KEY=0x123... ACCOUNT_ADDRESS=0x456... \
axis run --headless --world=my-world --auth=privatekey
description: Bypass Cartridge Controller, pay gas directly
note: No paymaster - you pay gas directly from the account
# Axis CLI - Error Codes Reference
# For AI agents: each error includes actionable resolution steps
errors:
# ============================================
# AUTHENTICATION ERRORS
# ============================================
- code: AUTH_SESSION_EXPIRED
message: Session expired
description: Cartridge Controller session has exceeded 7-day validity
action: REAUTHENTICATE
resolution:
command: axis auth {world} --method=password --username={user} --password={pass}
steps:
- Re-run authentication command
- Session will be refreshed for another 7 days
retry: false
- code: AUTH_PENDING
message: Auth remains pending
description: Browser approval flow was not completed
action: COMPLETE_AUTH
resolution:
steps:
- If redirect URL available: axis auth {world} --redirect-url="{url}"
- If session data available: axis auth {world} --session-data="{base64}"
- Otherwise, restart auth flow with axis auth {world}
retry: false
- code: AUTH_PASSWORD_FAILED
message: Password auth fails
description: Invalid username or password, or account lacks password credential
action: VERIFY_CREDENTIALS
resolution:
steps:
- Verify username and password are correct
- Ensure account has password credential on Cartridge
- Try interactive browser auth as fallback
retry: false
- code: AUTH_NO_SESSION
message: No session found
description: World has not been authenticated yet
action: AUTHENTICATE
resolution:
command: axis auth {world} --method=password --username={user} --password={pass}
retry: false
- code: AUTH_INVALID_CALLBACK
message: Invalid callback URL
description: Redirect URL format is incorrect or expired
action: RESTART_AUTH
resolution:
steps:
- Restart auth flow with axis auth {world}
- Complete browser approval within timeout
retry: false
# ============================================
# CONFIGURATION ERRORS
# ============================================
- code: CONFIG_MISSING_WORLD
message: --world is required for headless mode
description: Headless mode requires explicit world selection
action: ADD_WORLD_FLAG
resolution:
command: axis run --headless --world={name} --api-port={port}
steps:
- List available worlds with axis worlds
- Add --world={name} flag to command
retry: false
- code: CONFIG_MISSING_API_KEY
message: No API key configured
description: LLM provider API key not found
action: CONFIGURE_API_KEY
resolution:
steps:
- Set ANTHROPIC_API_KEY in ~/.eternum-agent/.env
- Or set OPENAI_API_KEY if using OpenAI provider
- Or export in shell environment
retry: false
- code: CONFIG_INVALID_PROVIDER
message: Invalid model provider
description: MODEL_PROVIDER value not recognized
action: FIX_PROVIDER
resolution:
valid_values: [anthropic, openai, openrouter, google]
steps:
- Set MODEL_PROVIDER to one of valid_values
retry: false
# ============================================
# NETWORK / DISCOVERY ERRORS
# ============================================
- code: DISCOVERY_NO_WORLDS
message: No worlds discovered
description: World discovery API returned no active worlds
action: CHECK_NETWORK
resolution:
steps:
- Check network connectivity
- Verify CARTRIDGE_API_BASE if overridden
- Wait and retry (worlds may be deploying)
retry: true
retry_after_seconds: 30
- code: DISCOVERY_NETWORK_ERROR
message: Network error during discovery
description: Failed to reach Cartridge discovery API
action: WAIT_AND_RETRY
resolution:
steps:
- Check internet connectivity
- Check if CARTRIDGE_API_BASE is reachable
- Retry after delay
retry: true
retry_after_seconds: 60
- code: RPC_CONNECTION_FAILED
message: Failed to connect to RPC
description: Could not establish connection to blockchain RPC
action: CHECK_RPC
resolution:
steps:
- Verify RPC_URL is correct if manually set
- Check network connectivity
- Try alternate RPC endpoint
retry: true
retry_after_seconds: 30
- code: TORII_CONNECTION_FAILED
message: Failed to connect to Torii
description: Could not establish connection to Torii indexer
action: CHECK_TORII
resolution:
steps:
- Verify TORII_URL is correct if manually set
- Check if Torii service is running
- Retry after delay
retry: true
retry_after_seconds: 30
# ============================================
# RUNTIME ERRORS
# ============================================
- code: MANIFEST_NOT_FOUND
message: Manifest not found
description: Contract manifest file missing or invalid
action: REINITIALIZE
resolution:
command: axis init {world}
steps:
- Run axis init {world} to regenerate manifests
- Or let axis auto-discover on next run
retry: false
- code: TRANSACTION_FAILED
message: On-chain transaction failed
description: Blockchain transaction was rejected
action: CHECK_GAS_AND_RETRY
resolution:
steps:
- Check account has sufficient gas token
- Verify action parameters are valid
- Retry with different parameters if applicable
retry: true
retry_after_seconds: 5
- code: LLM_API_ERROR
message: LLM API error
description: Error from LLM provider API
action: WAIT_AND_RETRY
resolution:
steps:
- Check API key validity
- Check rate limits on provider
- Retry after delay
retry: true
retry_after_seconds: 10
- code: LLM_RATE_LIMITED
message: LLM rate limited
description: Too many requests to LLM provider
action: WAIT_AND_RETRY
resolution:
steps:
- Increase TICK_INTERVAL_MS to reduce request frequency
- Wait for rate limit window to reset
retry: true
retry_after_seconds: 60
# ============================================
# HTTP API ERRORS
# ============================================
- code: API_INVALID_JSON
message: Invalid JSON in request body
description: Request body could not be parsed as JSON
action: FIX_REQUEST
resolution:
steps:
- Validate JSON syntax
- Ensure Content-Type is application/json
retry: false
- code: API_MISSING_CONTENT
message: Missing content field
description: POST /prompt requires content field
action: FIX_REQUEST
resolution:
example: '{"content": "your prompt here"}'
retry: false
- code: API_INVALID_CONFIG_PATH
message: Invalid config path
description: Config update path not recognized
action: FIX_REQUEST
resolution:
valid_paths:
- tickIntervalMs
- loopEnabled
- modelProvider
- modelId
retry: false
- code: API_NOT_ENABLED
message: HTTP API not enabled
description: Headless mode started without --api-port
action: ENABLE_API
resolution:
command: axis run --headless --world={world} --api-port=3000
retry: false
# ============================================
# HTTP STATUS CODE MAPPING
# ============================================
http_status_mapping:
400:
codes: [API_INVALID_JSON, API_MISSING_CONTENT, API_INVALID_CONFIG_PATH]
action: FIX_REQUEST
401:
codes: [AUTH_SESSION_EXPIRED, AUTH_NO_SESSION]
action: REAUTHENTICATE
404:
codes: [DISCOVERY_NO_WORLDS, MANIFEST_NOT_FOUND]
action: CHECK_RESOURCES
500:
codes: [LLM_API_ERROR, TRANSACTION_FAILED]
action: WAIT_AND_RETRY
503:
codes: [RPC_CONNECTION_FAILED, TORII_CONNECTION_FAILED, DISCOVERY_NETWORK_ERROR]
action: WAIT_AND_RETRY
# ============================================
# ACTION DEFINITIONS
# ============================================
actions:
REAUTHENTICATE:
description: Re-run authentication command
automatic: true
WAIT_AND_RETRY:
description: Wait specified time then retry operation
automatic: true
FIX_REQUEST:
description: Correct request parameters and retry
automatic: false
COMPLETE_AUTH:
description: Complete pending authentication flow
automatic: false
CHECK_NETWORK:
description: Verify network connectivity
automatic: false
CONFIGURE_API_KEY:
description: Set required API key in environment
automatic: false
ADD_WORLD_FLAG:
description: Add missing --world flag to command
automatic: true
# Example: Fleet orchestration pattern
name: Fleet orchestration
description: Running multiple agents across different worlds
# Step 1: Authenticate all worlds
authenticate_all:
command: axis auth --all --method=password --username=myuser --password=secret --json > /tmp/auth.json
output_file: /tmp/auth.json
output_example:
- world: world-alpha
status: authenticated
expires: "2026-03-12T06:50:00Z"
- world: world-beta
status: authenticated
expires: "2026-03-12T06:50:00Z"
- world: world-gamma
status: authenticated
expires: "2026-03-12T06:50:00Z"
# Step 2: Start agents for all worlds
start_fleet:
script: |
#!/bin/bash
# Read authenticated worlds
for world in $(jq -r '.[].world' /tmp/auth.json); do
# Generate random port between 3000-3999
PORT=$((3000 + RANDOM % 1000))
# Start agent in background
axis run --headless --world="$world" --api-port=$PORT \
>> /var/log/axis/$world.log 2>&1 &
# Record PID and port
echo "$world:$!:$PORT" >> /tmp/axis-fleet.txt
done
# Step 3: Monitor fleet
monitor_fleet:
script: |
#!/bin/bash
while read line; do
WORLD=$(echo $line | cut -d: -f1)
PID=$(echo $line | cut -d: -f2)
PORT=$(echo $line | cut -d: -f3)
# Check if process is running
if kill -0 $PID 2>/dev/null; then
STATUS=$(curl -s http://127.0.0.1:$PORT/status | jq -r '.status // "unknown"')
echo "$WORLD: running (PID $PID, port $PORT) - $STATUS"
else
echo "$WORLD: stopped"
fi
done < /tmp/axis-fleet.txt
# Step 4: Send command to all agents
broadcast_command:
script: |
#!/bin/bash
PROMPT="$1"
while read line; do
PORT=$(echo $line | cut -d: -f3)
curl -s -X POST http://127.0.0.1:$PORT/prompt \
-H 'Content-Type: application/json' \
-d "{\"content\":\"$PROMPT\"}"
done < /tmp/axis-fleet.txt
usage: ./broadcast.sh "Scout all directions"
# Step 5: Graceful shutdown
shutdown_fleet:
script: |
#!/bin/bash
while read line; do
PORT=$(echo $line | cut -d: -f3)
curl -s -X POST http://127.0.0.1:$PORT/shutdown
done < /tmp/axis-fleet.txt
# Systemd service example
systemd_service:
file: /etc/systemd/system/axis@.service
content: |
[Unit]
Description=Axis Agent for %i
After=network.target
[Service]
Type=simple
User=axis
Environment=ETERNUM_AGENT_HOME=/var/lib/axis
ExecStart=/usr/local/bin/axis run --headless --world=%i --api-port=0
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
usage: |
systemctl enable axis@world-alpha
systemctl start axis@world-alpha
# Example: Update runtime configuration via HTTP API
# Prerequisite: axis run --headless --world=my-world --api-port=3000
name: Update runtime configuration
endpoint: POST /config
description: Modify agent settings without restart
request:
method: POST
url: http://127.0.0.1:3000/config
headers:
Content-Type: application/json
body:
changes:
- path: tickIntervalMs
value: 30000
- path: loopEnabled
value: true
response:
status: 200
headers:
Content-Type: application/json
body:
status: updated
applied:
- path: tickIntervalMs
oldValue: 60000
newValue: 30000
- path: loopEnabled
oldValue: true
newValue: true
# Alternative: curl command
curl: |
curl -X POST http://127.0.0.1:3000/config \
-H 'Content-Type: application/json' \
-d '{"changes":[{"path":"tickIntervalMs","value":30000}]}'
# Available config paths
available_paths:
- name: tickIntervalMs
type: integer
description: Time between ticks in milliseconds
default: 60000
- name: loopEnabled
type: boolean
description: Whether auto-tick loop is active
default: true
- name: modelProvider
type: string
description: LLM provider name
values: [anthropic, openai, openrouter, google]
default: anthropic
- name: modelId
type: string
description: Model identifier
default: claude-sonnet-4-5-20250929
# Example: Send prompt to agent via HTTP API
# Prerequisite: axis run --headless --world=my-world --api-port=3000
name: Send prompt to agent
endpoint: POST /prompt
description: Queue a text prompt for the agent to process
request:
method: POST
url: http://127.0.0.1:3000/prompt
headers:
Content-Type: application/json
body:
content: "Build a farm at your main realm"
response:
status: 200
headers:
Content-Type: application/json
body:
status: queued
prompt_id: "pmt_abc123"
# Alternative: curl command
curl: |
curl -X POST http://127.0.0.1:3000/prompt \
-H 'Content-Type: application/json' \
-d '{"content":"Build a farm at your main realm"}'
# Example: Controlling agent via stdin (headless mode)
name: Stdin control
description: Send commands via stdin when --stdin is set or stdin is non-TTY
# Prerequisites
setup:
command: axis run --headless --world=my-world --stdin
note: Each command is a single JSON object on its own line (NDJSON)
# Command types
commands:
# Send a prompt
- type: prompt
description: Queue a prompt for the agent to process
input: '{"type":"prompt","content":"Scout north"}'
response_event:
type: prompt
status: queued
content: "Scout north"
# Update configuration
- type: config
description: Update runtime settings
input: '{"type":"config","changes":[{"path":"tickIntervalMs","value":45000}]}'
response_event:
type: config
applied:
- path: tickIntervalMs
value: 45000
# Multiple config changes
- type: config_multi
description: Update multiple settings at once
input: |
{"type":"config","changes":[{"path":"tickIntervalMs","value":30000},{"path":"loopEnabled","value":false}]}
response_event:
type: config
applied:
- path: tickIntervalMs
value: 30000
- path: loopEnabled
value: false
# Graceful shutdown
- type: shutdown
description: Request graceful shutdown
input: '{"type":"shutdown"}'
response_event:
type: shutdown
status: initiated
# Full session example
full_session:
description: Example of a complete stdin control session
script: |
# Start agent with stdin enabled
axis run --headless --world=my-world --stdin &
AGENT_PID=$!
# Wait for startup
sleep 5
# Send commands via stdin
echo '{"type":"prompt","content":"Check resources"}' > /proc/$AGENT_PID/fd/0
echo '{"type":"config","changes":[{"path":"tickIntervalMs","value":30000}]}' > /proc/$AGENT_PID/fd/0
# Let agent run
sleep 60
# Shutdown
echo '{"type":"shutdown"}' > /proc/$AGENT_PID/fd/0
wait $AGENT_PID
# Pipe commands from file
from_file:
description: Execute commands from a file
commands_file: |
{"type":"prompt","content":"Scout north"}
{"type":"prompt","content":"Build farm at main base"}
{"type":"config","changes":[{"path":"tickIntervalMs","value":45000}]}
execution: |
cat commands.jsonl | axis run --headless --world=my-world --stdin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment