How to Configure Lieutenant Backend and Override Options in SwarmForge
TL;DR: SwarmForge configures the lieutenant AI backend through a line-based config file at swarmforge/swarmforge.conf, falling back to the SWARMFORGE_LIEUTENANT_AGENT environment variable or defaulting to grok if neither is set.
SwarmForge uses a lightweight configuration system to determine which AI backend powers the lieutenant role. According to the unclebob/swarm-forge source code, this configuration is handled by the parse-lieutenant-config function in swarmforge/scripts/swarmforge.bb (lines 887-904). Understanding how to configure the lieutenant backend and override its options lets you switch between agents like grok, claude, or codex without modifying the core codebase.
Configuration File Location and Format
SwarmForge reads lieutenant settings from swarmforge/swarmforge.conf at startup. This file uses a simple line-based format:
- Comment lines start with
#or are blank - Active configuration lines contain space-separated fields
- The
lieutenantkeyword (case-insensitive) triggers backend selection
A valid lieutenant line requires at least two fields:
Lieutenant <agent-name> [extra-args...]
- Field 1: The literal word
lieutenant - Field 2: The agent name (validated against
known-agents) - Field 3+: Optional arguments passed verbatim to the agent
Example configuration:
# swarmforge/swarmforge.conf
Lieutenant claude --temperature 0.7 --max-tokens 1024
Priority of Configuration Methods
SwarmForge resolves the lieutenant backend through a three-tier fallback system:
| Priority | Method | When Applied |
|---|---|---|
| 1 (Highest) | swarmforge.conf lieutenant line |
Used whenever present and valid |
| 2 | SWARMFORGE_LIEUTENANT_AGENT environment variable |
Used when config file lacks a lieutenant line |
| 3 (Lowest) | Default agent grok |
Used when neither config nor env-var is set |
Method 1: Edit swarmforge.conf
Add or modify the lieutenant line directly in your configuration file:
# swarmforge/swarmforge.conf
Lieutenant codex --verbose
This takes precedence over all other methods.
Method 2: Environment Variable Override
Export SWARMFORGE_LIEUTENANT_AGENT before running SwarmForge:
export SWARMFORGE_LIEUTENANT_AGENT=claude
./swarm
The environment variable only applies when swarmforge.conf contains no lieutenant line.
Method 3: Default Behavior
With no configuration, SwarmForge launches:
{:agent "grok" :extra-args nil}
Code Flow: How Configuration Becomes Execution
The lieutenant backend selection follows this execution path in swarmforge/scripts/swarmforge.bb:
run-host!orrun-project!builds the contextctxlieutenant-rowcallsparse-lieutenant-configwithctxparse-lieutenant-configreturns a map{:agent "..." :extra-args "..."}window-rowconstructs a tmux session specification using these valueslaunch-commandspawns the lieutenant pane with the final agent command
The parse-lieutenant-config function implements the full fallback logic:
;; swarmforge/scripts/swarmforge.bb (lines 887-904)
(defn parse-lieutenant-config [ctx]
(let [file (:config-file ctx)
fallback (str/lower-case
(or (not-empty (System/getenv "SWARMFORGE_LIEUTENANT_AGENT"))
"grok"))]
(if-not (fs/regular-file? file)
{:agent fallback :extra-args nil}
(or (some (fn [raw]
(let [line (str/trim raw)]
(when-not (skip-config-line? line)
(let [fields (str/split line #"\s+")]
(when (and (>= (count fields) 2)
(= (str/lower-case (first fields)) "lieutenant"))
(let [agent (str/lower-case (second fields))]
(reject-if (not (known-agents agent))
(str "Unsupported agent '" (second fields)
"' for lieutenant"))
{:agent agent
:extra-args (extra-args-str (drop 2 fields))}))))))
(str/split-lines (slurp (str file))))
{:agent fallback :extra-args nil}))))
Key behaviors in this implementation:
- Agent validation: Unknown agents trigger an error via
reject-ifagainst theknown-agentswhitelist - Case insensitivity: Both
LIEUTENANTandlieutenantare valid - Extra args preservation: All fields after the agent name are joined and passed through
extra-args-str
Practical Configuration Examples
Default grok with No Configuration
# swarmforge/swarmforge.conf
# (no lieutenant line)
Result: Lieutenant launches with grok and no extra arguments.
Claude with Temperature Control
# swarmforge/swarmforge.conf
Lieutenant claude --temperature 0.7 --max-tokens 1024
Result: The tmux pane executes approximately:
claude --temperature 0.7 --max-tokens 1024 ...
Environment Override for Temporary Switching
# Ensure no lieutenant line in swarmforge.conf
export SWARMFORGE_LIEUTENANT_AGENT=codex
./swarm my-project
Result: Uses codex without modifying configuration files.
Combined Documentation and Active Config
# swarmforge/swarmforge.conf
# Development: use claude with relaxed constraints
Lieutenant claude --thought
# Production (commented out):
# Lieutenant grok --strict
Key Files Reference
| File | Purpose | Location in Repository |
|---|---|---|
swarmforge/swarmforge.conf |
User-editable configuration with optional lieutenant line |
[swarmforge/swarmforge.conf](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) |
swarmforge/scripts/swarmforge.bb |
Core script containing parse-lieutenant-config and launch logic |
swarmforge/scripts/swarmforge.bb |
swarmforge/roles/lieutenant.prompt |
Prompt template read by the lieutenant at session start | swarmforge/roles/lieutenant.prompt |
Summary
- Primary configuration happens in
swarmforge/swarmforge.confusing alieutenant <agent> [args...]line format - Environment variable
SWARMFORGE_LIEUTENANT_AGENTserves as fallback when no config line exists - Default agent is
grokwhen neither source provides a value - The
parse-lieutenant-configfunction inswarmforge.bbenforces agent validation againstknown-agents - Extra arguments pass through verbatim to the agent command, enabling backend-specific tuning
Frequently Asked Questions
What happens if I specify an unsupported agent in swarmforge.conf?
SwarmForge validates the agent name against a whitelist (known-agents). If you specify an unknown agent, parse-lieutenant-config calls reject-if and throws an error with the message "Unsupported agent '<name>' for lieutenant". The session will not start until you correct the configuration.
Can I use multiple lieutenant configurations for different projects?
The current implementation uses a single global configuration file at swarmforge/swarmforge.conf. For per-project overrides, use the SWARMFORGE_LIEUTENANT_AGENT environment variable in project-specific wrapper scripts, or maintain separate config files and symlink them before running ./swarm.
Why does my environment variable not take effect?
The SWARMFORGE_LIEUTENANT_AGENT variable only applies when swarmforge.conf contains no lieutenant line. Check that your config file does not have an active lieutenant entry, as explicit configuration always wins over environment variables according to the priority rules in parse-lieutenant-config.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →