Skip to main content

PROJECT.md — Fleet-Wide Context

Shared across all agents. Loaded into every agent’s system prompt as part of the 48K-char bootstrap injection.
# PROJECT.md

## What We're Building
SaaS platform for automated lead qualification

## Current Priority
Ship the email personalization pipeline this week

## Hard Constraints
- Budget: $50/day total across all agents
- No cold outreach to .edu or .gov domains
PROJECT.md is read-only at runtime — agents cannot modify it. Update it from the engine dashboard or via the /project REPL command. (The operator agent also has a update_project_context tool that proposes changes for confirmation.)

config/mesh.yaml — Framework Settings

mesh:
  host: "0.0.0.0"
  port: 8420

llm:
  default_model: "openai/gpt-4.1-mini"     # wizard suggestion; engine fallback is "openai/gpt-4o-mini"
  embedding_model: "text-embedding-3-small"  # 1536 dims (OpenAI); non-OpenAI providers degrade to keyword-only
  max_tokens: 4096
  temperature: 0.7
  # Per-model failover chain — agents retry the next entry on per-model health failure
  failover_chains:
    "anthropic/claude-sonnet-4-6":
      - "openai/gpt-4.1-mini"
      - "openai/gpt-4o-mini"

channels:
  telegram:
    default_agent: assistant
  discord:
    default_agent: assistant
  slack: {}
  whatsapp: {}
Channels use token-presence activation — there is no enabled: true/false flag. A channel auto-starts when its bot token resolves through the credential vault. Resolution order: OPENLEGION_SYSTEM_<NAME>OPENLEGION_CRED_<NAME> → bare env → mesh.yaml channels.<name>.bot_token. Remove the token to disable the channel.

Agent Definitions

There is no top-level config/agents.yaml shipped with the engine. Agents are defined one of three ways:
  1. Templates in src/templates/*.yaml (the 13 fleet templates).
  2. Dashboard / operator tools at runtime (the operator agent’s create_agent, edit_agent, and apply_template tools, or the engine dashboard’s Team tab).
  3. REPL via /add while openlegion start is running.
Each agent record carries:
FieldTypeDescription
rolestringAgent’s role identifier (template-fixed when applied from a template)
modelstringLiteLLM model id (e.g., openai/gpt-4.1-mini, anthropic/claude-sonnet-4-6)
skills_dirstringPath to custom skills directory
system_promptstringCustom system prompt override (replaces the default)
initial_instructionsstringInitial INSTRUCTIONS.md content (≤12K chars)
soulstringInitial SOUL.md content / persona (≤4K chars)
initial_interfacestringInitial INTERFACE.md content (≤4K chars)
heartbeatstringInitial HEARTBEAT.md content (uncapped)
thinkingstringExtended thinking: off (default), low, medium, or high
resources.memory_limitstringContainer memory (worker default: 384m; operator: 128m)
resources.cpu_limitfloatCPU quota (worker default: 0.15; operator: 0.05)
budget.daily_usdfloatDaily LLM spend cap (default 10.00; operator clamp: 0.01-1000)
budget.monthly_usdfloatMonthly LLM spend cap (default 200.00; operator clamp: 0.10-30000)
mcp_serverslistMCP tool servers — stdio transport only
Container hardening is enforced by the runtime: UID 1000, cap_drop=ALL, no-new-privileges, read-only filesystem, tmpfs=/tmp 100m noexec/nosuid, pids_limit=256. These are not user-tunable.

config/permissions.json — Agent Permissions

Per-agent access control. Default policy: deny. A missing file denies everything. You may include a "default" template that other agents inherit from.
{
  "default": {
    "can_message": ["*"],
    "blackboard_read": ["context/*", "tasks/*"]
  },
  "researcher": {
    "can_message": ["operator", "writer"],
    "can_publish": ["research_complete"],
    "can_subscribe": ["new_lead"],
    "blackboard_read": ["tasks/*", "context/*"],
    "blackboard_write": ["context/prospect_*"],
    "allowed_apis": ["llm", "web_search"],
    "allowed_credentials": ["brightdata_*"],
    "can_use_browser": true,
    "browser_actions": ["*"],
    "can_manage_cron": true
  }
}

Permission Fields

FieldTypeDescription
can_messagelistAgents this agent can send messages to
can_publishlistPub/sub topics this agent can publish to
can_subscribelistPub/sub topics this agent can subscribe to
blackboard_readlistGlob patterns for readable blackboard keys
blackboard_writelistGlob patterns for writable blackboard keys
allowed_apislistExternal APIs accessible through the vault
allowed_credentialslistfnmatch globs (case-insensitive) for agent-tier credentials; ["*"] = all agent-tier; system creds always blocked
can_use_browserboolAccess browser service container (default false)
browser_actionslist / nullAllowlist of browser action names; null or ["*"] = all known; [] = deny
can_spawnboolSpawn ephemeral fleet agents (default false; operator cannot grant this)
can_manage_cronboolCreate/update/delete cron jobs
can_use_walletboolUse wallet tools (default false; operator cannot grant this)
wallet_allowed_chainslistEVM / Solana chain ids the agent may use
wallet_spend_limit_per_tx_usdfloatPer-transaction USD cap (default 10.0)
wallet_spend_limit_daily_usdfloatDaily USD cap (default 100.0)
wallet_rate_limit_per_hourintWallet ops per hour (default 10)
wallet_allowed_contractslistContract address allowlist (empty = native transfers only)
Control-plane flags (six; defaults are true for the operator, false for workers): can_manage_fleet, can_manage_projects, can_edit_agent_config, can_view_fleet_metrics, can_route_tasks, can_request_user_credentials. Operator ceiling: the operator cannot grant can_spawn=true or can_use_wallet=true to any agent — those flags must be edited directly in permissions.json (or via a setting-level tool that bypasses the operator).

.env — API Keys and Runtime Tunables

Managed automatically by openlegion start and the /addkey REPL command. Can also be edited directly. The file is rewritten atomically with chmod 0o600; keys are validated against ^[A-Za-z_][A-Za-z0-9_]*$ and \r\n is rejected in keys/values to prevent env injection.
# System tier — LLM provider keys (mesh-only; never accessible by agents)
OPENLEGION_SYSTEM_ANTHROPIC_API_KEY=sk-ant-...
OPENLEGION_SYSTEM_OPENAI_API_KEY=sk-...
OPENLEGION_SYSTEM_MOONSHOT_API_KEY=sk-...

# OAuth blobs (Anthropic Claude CLI / OpenAI Codex CLI imports)
# OPENLEGION_SYSTEM_ANTHROPIC_OAUTH={...}
# OPENLEGION_SYSTEM_OPENAI_OAUTH={...}

# Wallet (per-agent EVM + Solana keys derive from this)
# OPENLEGION_SYSTEM_WALLET_MASTER_SEED="word1 word2 ... word24"
# OPENLEGION_SYSTEM_WALLET_LIMIT_PER_TX_USD=10
# OPENLEGION_SYSTEM_WALLET_DAILY_USD=100
# OPENLEGION_SYSTEM_WALLET_RATE_LIMIT_PER_HOUR=10

# Agent tier — tool/service keys (access controlled per-agent via allowed_credentials)
OPENLEGION_CRED_WEB_SEARCH_API_KEY=...

# Channel tokens (presence of the token activates the channel — no separate enable flag)
OPENLEGION_CRED_TELEGRAM_BOT_TOKEN=123456:ABC...
OPENLEGION_CRED_DISCORD_BOT_TOKEN=MTIz...
OPENLEGION_CRED_SLACK_BOT_TOKEN=xoxb-...
OPENLEGION_CRED_SLACK_APP_TOKEN=xapp-...
OPENLEGION_CRED_WHATSAPP_ACCESS_TOKEN=EAAx...
OPENLEGION_CRED_WHATSAPP_PHONE_NUMBER_ID=1234...
WHATSAPP_APP_SECRET=...                  # REQUIRED in prod; otherwise channel raises RuntimeError

# Runtime tunables
OPENLEGION_LOG_FORMAT=text                # "json" (default) or "text"
OPENLEGION_TOOL_TIMEOUT=300               # tool execution timeout in seconds
OPENLEGION_MAX_ITERATIONS=20              # task-mode iteration cap (clamp 1-100)
OPENLEGION_CHAT_MAX_TOOL_ROUNDS=30        # chat per-turn tool rounds (clamp 1-200)
OPENLEGION_CHAT_MAX_TOTAL_ROUNDS=200      # chat total rounds (clamp 1-1000)
OPENLEGION_ORCHESTRATION_TASKS_V2=1       # durable task records (default ON)
OPENLEGION_MAX_AGENTS=0                   # 0 = unlimited (but counter-intuitively falls into Basic browser tier)
OPENLEGION_MAX_PROJECTS=                  # unset = unlimited; 0 = disabled; N>0 = capped
OPENLEGION_PROJECT_SCOPE_MODE=enforce
OPENLEGION_BROWSER_MAX_CONCURRENT=        # clamp 1-64; legacy alias MAX_BROWSERS
OPENLEGION_SYSTEM_* keys are reserved for mesh-tier use (LLM proxy, wallet seed, etc.) and are never accessible to agents. OPENLEGION_CRED_* keys are agent-tier — access is controlled per-agent via the allowed_credentials field in permissions. Agents reference them as opaque $CRED{name} handles in tool arguments; the real value is substituted in the mesh.
OPENLEGION_MAX_AGENTS=0 (default) means “unlimited agents” but falls into the Basic browser-service tier (2GB / 512MB / 1.0 CPU / 1 browser). Set it explicitly to scale browser-service resources: 2-5 → Growth, 6-15 → Pro, >15 → Pro Max.

Other Config Locations

PathPurpose
config/mesh.yamlMesh host, LLM defaults, channel routing
config/permissions.jsonPer-agent ACL matrix
config/cron.jsonCron / heartbeat state (auto-managed)
config/projects/{name}/Per-project metadata + project.md
config/settings.jsonDashboard-managed browser flags & runtime overrides (4 CAPTCHA-solver-cred names are blacklisted from this file at load — env-only)
config/api_keys.jsonNamed API keys for the mesh (stored as salted SHA-256 hashes)
config/network.yamlno_proxy exclusion list
data/captcha_costs.jsonCAPTCHA spend ledger in millicents (chmod 0o600)
data/costs.dbPer-agent + per-project LLM cost ledger (SQLite WAL)
.envAPI keys / credentials

Browser Flags (config/settings.json / env)

53 entries in KNOWN_FLAGS group into: profile / network (BROWSER_OS, _LOCALE, _UA_VERSION, _DEVICE_PROFILE, HTTP/HTTPS proxy fields, egress allowlist), CAPTCHA solver, CAPTCHA timeouts, CAPTCHA solver proxy, CAPTCHA pacing, CAPTCHA cost caps, operator kill switches (BROWSER_DOWNLOADS_DISABLED, BROWSER_NETWORK_INSPECT_DISABLED, BROWSER_COOKIE_IMPORT_DISABLED, CAPTCHA_DISABLED), snapshot / screenshot, behavior recorder, upload staging, session continuity, browser concurrency. The four CAPTCHA-solver credential names (CAPTCHA_SOLVER_KEY, _SECONDARY, CAPTCHA_SOLVER_PROXY_LOGIN, _PASSWORD) are _ENV_ONLY_FLAGS — they are stripped from config/settings.json at load and must be supplied via environment.