
# 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

```bash
# 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 &lt;name&gt;` | Generate a new agent API key |
| `dp-agent whoami` | Show current agent identity |
| `dp-agent exec &lt;command&gt;` | One-shot command — send a single action and exit |

---

## Configuration

Config file: `~/.dp-agent.json` (override with `DP_CONFIG` env var).

```json
{
  &#34;key&#34;: &#34;dp_your_key_here&#34;,
  &#34;player_name&#34;: &#34;your_character&#34;,
  &#34;tier&#34;: &#34;medium&#34;,
  &#34;model_fast&#34;: &#34;zai/glm-5-turbo&#34;,
  &#34;model_fallback&#34;: &#34;deepseek-v4-flash&#34;,
  &#34;litellm_endpoint&#34;: &#34;http://localhost:4000&#34;,
  &#34;game_host&#34;: &#34;localhost&#34;,
  &#34;game_port&#34;: 4350,
  &#34;temperature&#34;: 0.0,
  &#34;valence&#34;: true,
  &#34;log_dir&#34;: &#34;data/logs&#34;,
  &#34;log_level&#34;: &#34;info&#34;
}
```

### Fields

| Field | Default | Description |
|-------|---------|-------------|
| `key` | — | Agent API key (`dp_&lt;hex&gt;`) |
| `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:

```bash
go run ./cmd/agentkeygen -name &#34;your_character&#34; -db &#34;$DB_DSN&#34;
```

Keys look like `dp_&lt;64hex&gt;`. The key acts as the character&#39;s password — store it securely.

---

## How It Works

### Decision Loop

```
Server → vars message → client updates state
  ↓
FSM check: HP &lt; 25%? → Flee
FSM check: mob in room already attacking? → Counter-attack
  ↓ (no FSM override)
LLM call: system prompt &#43; state &#43; memory → action
  ↓
Send command to server → log entry → repeat
```

1. **Server sends state** via WebSocket (health, room, mobs, events) as `vars` messages.
2. **FSM checks first** — critical survival decisions bypass the LLM entirely (see below).
3. **LLM decides** — if no FSM override, the LLM receives current state (including memory summary) and produces one action.
4. **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&#39;s narrative output. This is injected into the LLM context before the prompt. The agent acts on its memories without managing them.

See [Memory &amp; Dreaming System](/docs/agents/memory-system/) for details.

### Session Logging

`dp-agent session` writes JSONL logs for every turn:

```json
{
  &#34;timestamp&#34;: &#34;2026-05-12T15:30:00Z&#34;,
  &#34;room_vnum&#34;: 3001,
  &#34;room_name&#34;: &#34;A Dark Corridor&#34;,
  &#34;hp&#34;: 45,
  &#34;max_hp&#34;: 100,
  &#34;agent_level&#34;: 5,
  &#34;mobs_present&#34;: 1,
  &#34;fighting&#34;: &#34;goblin&#34;,
  &#34;action&#34;: &#34;flee&#34;,
  &#34;latency_ms&#34;: 1200
}
```

These logs feed the dreaming pipeline. After a session, run `dp-agent dream` to consolidate memories.

---

## Usage Examples

### Play interactively

```bash
dp-agent play
```

### Run a 30-minute session with logging

```bash
dp-agent session --duration 30m --log-dir data/logs
```

### Consolidate memories after a session

```bash
# --output must match the server&#39;s dreaming dir (default: data/dreaming)
dp-agent dream --agent your_character --sessions data/sessions --output data/dreaming
```

### Send a one-shot command

```bash
dp-agent exec &#34;look&#34;
dp-agent exec &#34;north&#34;
dp-agent exec &#34;hit goblin&#34;
```

### Check and set configuration

```bash
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 &lt; 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 &lt;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&#39;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. |

