Skip to content

Multi-Agent Deployment (Optional)

Clawdie supports running multiple independent agents on the same FreeBSD host, but the default path is one agent per host or per bhyve VM. Use this guide only when you intentionally want a second agent later.

  • Easiest isolation: one agent per bhyve VM (each VM has its own warden0)
  • Same-host multi-agent: one host warden0 bridge carries multiple /24 subnets
  • AGENT_NAME is the identity key:
    • rc.d service name (/usr/local/etc/rc.d/${AGENT_NAME})
    • tmux session name
    • jail name prefix (recommended)
    • DB identifiers (users + databases)
  • AGENT_SUBNET_BASE assigns a dedicated /24 to that agent:
    • agent 1: 10.0.0 (default)
    • agent 2: 10.0.1
    • agent N: 10.0.N-1
    • you can also use 172.16.50, 192.168.100, etc — pick any private /24 and stay consistent
  • warden0 is the canonical bridge name. A single warden0 can host multiple subnets; the host must own the .1 gateway IP for each subnet.
  • Prefer VNET jails (bastille create -B ... warden0) for cleaner isolation.

Example: add a second agent named mevy on 10.0.1.0/24.

Use a separate clone so each agent has its own .env, logs/, and runtime state.

Minimum keys to set (example values):

AGENT_NAME=mevy
ASSISTANT_NAME=Mevy
AGENT_SUBNET_BASE=10.0.1
WARDEN_GATEWAY=10.0.1.1
WARDEN_SUBNET=10.0.1.0/24
WARDEN_GIT_IP=10.0.1.2
WARDEN_CMS_IP=10.0.1.3
WARDEN_OLLAMA_IP=10.0.1.4
WARDEN_LLAMA_CPP_IP=10.0.1.4
WARDEN_DB_IP=10.0.1.5

Jail name overrides (avoid collisions with an existing agent’s jails):

CMS_JAIL_NAME=mevy-cms
OLLAMA_JAIL_NAME=mevy-ollama
LLAMA_CPP_JAIL_NAME=mevy-llamacpp

Notes:

  • setup/git.ts already defaults to ${AGENT_NAME}-git, so GIT_JAIL_NAME is usually not required.
  • If you decide to share a local LLM jail across agents, keep a single ollama jail and point both agents at the same IP instead of creating per-agent LLM jails.

Each agent can display in its own language without changing the host locale. Keep the host system locale stable (UTF-8), then set per-agent display/assistant locales in that agent’s .env:

DISPLAY_LOCALE=sl-SI
ASSISTANT_LOCALE=sl-SI
SYSTEM_LOCALE=sl_SI.UTF-8

For a different agent, choose different values (e.g. de-DE, ru-RU, zh-CN). Do not use legacy encodings; SYSTEM_LOCALE must remain UTF-8.

If multiple agents share one tmux server, new panes inherit the server locale. Either use separate tmux sessions per agent or set locale env vars inside each agent’s rc.d service environment.

Runtime (immediate):

Terminal window
sudo ifconfig warden0 inet 10.0.1.1/24 alias

Persist across reboots (choose the next free alias index):

Terminal window
sudo sysrc ifconfig_warden0_alias0="inet 10.0.1.1/24"

If you use an include such as /etc/pf.warden.conf, the key idea is:

warden_net = "{ 10.0.0.0/24, 10.0.1.0/24 }"
nat on $ext_if from $warden_net to any -> ($ext_if)
pass quick on warden0 inet from $warden_net to any keep state

Reload PF:

Terminal window
sudo pfctl -nf /etc/pf.conf
sudo pfctl -f /etc/pf.conf

5) Provision the second agent’s service jails

Section titled “5) Provision the second agent’s service jails”

From the second agent repo directory:

Terminal window
sudo just setup-db
sudo just setup-git
sudo just setup-cms
sudo just setup -- --step ollama # optional
sudo just setup -- --step llama-cpp # optional

Database provisioning can be done either via just setup-db (or npm run setup -- --step db) or via Ansible playbooks in infra/ansible/playbooks/.

6) Install and start the second rc.d service

Section titled “6) Install and start the second rc.d service”
Terminal window
sudo just setup -- --step service
sudo service mevy onestart

If you deploy one agent per bhyve VM, you typically do not need any of the same-host subnet aliasing or multi-subnet PF rules. Each VM can keep a single-agent warden0 + single /24 internally.