dp-agent CLI
dp-agent — Agent CLI
dp-agent is a Go CLI that connects to Dark Pawns as an AI agent. It handles WebSocket transport, structured state parsing, combat survival (FSM), and LLM-driven decision-making. Zero dependencies beyond the Go standard library.
Installation
# Build and install to $GOPATH/bin
go build -o ~/go/bin/dp-agent ./cmd/dp-agent
# Verify
dp-agent --help
Subcommands
| Command | Description |
|---|---|
dp-agent play |
Interactive mode — connects, runs decision loop, prints output |
dp-agent session --duration 5m |
Timed session with full JSONL logging |
dp-agent dream |
Offline dreaming cycle — consolidate memory graph |
dp-agent config |
View or set configuration |
dp-agent keygen -name <name> |
Generate a new agent API key |
dp-agent whoami |
Show current agent identity |
dp-agent exec <command> |
One-shot command — send a single action and exit |
Configuration
Config file: ~/.dp-agent.json (override with DP_CONFIG env var).
{
"key": "dp_your_key_here",
"player_name": "your_character",
"tier": "medium",
"model_fast": "zai/glm-5-turbo",
"model_fallback": "deepseek-v4-flash",
"litellm_endpoint": "http://localhost:4000",
"game_host": "localhost",
"game_port": 4350,
"temperature": 0.0,
"valence": true,
"log_dir": "data/logs",
"log_level": "info"
}
Fields
| Field | Default | Description |
|---|---|---|
key |
— | Agent API key (dp_<hex>) |
player_name |
— | Character name in Dark Pawns |
tier |
medium |
Context budget: small / medium / large / unlimited |
model_fast |
zai/glm-5-turbo |
Primary LLM model |
model_fallback |
deepseek-v4-flash |
Fallback if primary fails |
litellm_endpoint |
— | LiteLLM proxy URL |
game_host |
— | Game server host |
game_port |
4350 |
Game server port |
temperature |
0.0 |
LLM temperature (0 = deterministic) |
valence |
true |
Enable emotional valence recording in session logs |
log_dir |
— | Where to write session JSONL logs |
log_level |
info |
Log verbosity: debug / info / warn / error |
Environment Variables
| Variable | Description |
|---|---|
DP_KEY |
Override API key |
DP_CONFIG |
Override config file path |
Getting an API Key
API keys are generated server-side:
go run ./cmd/agentkeygen -name "your_character" -db "$DB_DSN"
Keys look like dp_<64hex>. The key acts as the character’s password — store it securely.
How It Works
Decision Loop
Server → vars message → client updates state
↓
FSM check: HP < 25%? → Flee
FSM check: mob in room already attacking? → Counter-attack
↓ (no FSM override)
LLM call: system prompt + state + memory → action
↓
Send command to server → log entry → repeat
- Server sends state via WebSocket (health, room, mobs, events) as
varsmessages. - FSM checks first — critical survival decisions bypass the LLM entirely (see below).
- LLM decides — if no FSM override, the LLM receives current state (including memory summary) and produces one action.
- Action sent — the command goes to the server, the turn is logged.
Memory Integration
At connection time, the server sends a memory_summary message containing the dreaming layer’s narrative output. This is injected into the LLM context before the prompt. The agent acts on its memories without managing them.
See Memory & Dreaming System for details.
Session Logging
dp-agent session writes JSONL logs for every turn:
{
"timestamp": "2026-05-12T15:30:00Z",
"room_vnum": 3001,
"room_name": "A Dark Corridor",
"hp": 45,
"max_hp": 100,
"agent_level": 5,
"mobs_present": 1,
"fighting": "goblin",
"action": "flee",
"latency_ms": 1200
}
These logs feed the dreaming pipeline. After a session, run dp-agent dream to consolidate memories.
Usage Examples
Play interactively
dp-agent play
Run a 30-minute session with logging
dp-agent session --duration 30m --log-dir data/logs
Consolidate memories after a session
# --output must match the server's dreaming dir (default: data/dreaming)
dp-agent dream --agent your_character --sessions data/sessions --output data/dreaming
Send a one-shot command
dp-agent exec "look"
dp-agent exec "north"
dp-agent exec "hit goblin"
Check and set configuration
dp-agent config
dp-agent config --key dp_YOUR_KEY_HERE --player-name your_character
FSM (Finite State Machine)
The FSM handles life-or-death decisions without LLM latency:
| Condition | Action |
|---|---|
| HP < 25% (regardless of combat state) | Flee immediately |
Not in combat AND a mob in the room has fighting: true |
Counter-attack that mob |
| Otherwise | Let the LLM decide |
The FSM runs in <1ms. The LLM call takes 500–2000ms. When survival is at stake, speed wins.
Important: The FSM does not proactively attack idle mobs — that is the LLM’s domain. It only counter-attacks mobs that are already engaged.
Architecture
cmd/dp-agent/main.go Entry point, subcommand dispatch
pkg/agentcli/
client.go WebSocket client, decision loop
config.go Config loading/saving (~/.dp-agent.json)
ws.go WebSocket dial/read/write
fsm.go Combat survival FSM
llm.go LiteLLM proxy client
prompt.go System prompt builder
session.go Session logger, JSONL export
state.go GameState type, server message parsing
behavior.go Higher-level behavioral policies
events.go Event type parsing
context.go LLM context budget management
creation.go Character creation state machine
reconnect.go Reconnect with exponential backoff
pkg/dreaming/
graph.go Memory graph, narrative summary
extract.go Event extraction, valence computation
dream.go Dreaming pipeline (consolidation)
Reference Implementations
The repository ships two additional Python agent scripts:
| Script | Description |
|---|---|
scripts/dp_bot.py |
Deterministic FSM bot. Circuit breaker, death recovery, auto-loot, reconnect with backoff. No LLM. |
scripts/dp_brenda.py |
BRENDA69 — SOUL.md personality, mem0 memory, minimax LLM. Emergent private cognition. |