Adds an in-dashboard AI assistant that answers questions about live game
state. Designed reactively (no background loops) — every user message in
the chat window or via /api/agent/ask runs one `claude -p` invocation.
Architecture:
- New host-side FastAPI service (agent/) on 127.0.0.1:8767, OUTSIDE the
dereth-tracker Docker container because `claude` and ~/.claude
credentials live on the host.
- nginx routes /api/agent/* to the host service.
- The same browser session cookie the tracker issues authenticates
agent requests (shared SECRET_KEY).
- The agent shells out to `claude -p --session-id <uuid>` with
cwd=/home/erik/MosswartOverlord. Sessions persist as JSONL on disk
via Claude Code's built-in machinery.
- An MCP stdio server (agent/mcp_overlord.py) exposes tools to Claude:
get_live_players, get_recent_rares, query_telemetry_db (read-only,
parsed by sqlglot to reject DML/DDL), get_player_state, get_inventory,
get_inventory_search, get_combat_stats, get_equipment_cantrips,
get_quest_status, get_server_health, suitbuilder_search.
- Read-only PG role (overlord_agent_ro) is the second line of defense
on the SQL tool — even a parser bypass can't mutate.
Frontend:
- AgentWindow.tsx — draggable chat window with localStorage-pinned
session UUID, "New Chat" button, on-mount rehydration from
/agent/sessions/{id}/history (parses Claude Code's JSONL).
- Wired into WindowRenderer + Sidebar (🤖 Assistant button).
Operational:
- systemd unit (overlord-agent.service) + install.sh.
- agent/README.md documents env vars, deploy flow, smoke tests.
- nginx/overlord.conf gets a new /api/agent/ location with 180s timeout.
- CLAUDE.md gets an "Overlord Assistant Mode" section briefing the
agent on which tools to use and how to behave.
NOT YET DEPLOYED — server still needs:
1. Apply agent/sql/0001_overlord_agent_ro.sql + ALTER ROLE password
2. Add AGENT_DB_DSN to /home/erik/MosswartOverlord/.env
3. bash agent/install.sh (creates venv, installs unit, starts service)
4. sudo cp /home/erik/MosswartOverlord/nginx/overlord.conf to nginx + reload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
46 lines
1.2 KiB
Bash
46 lines
1.2 KiB
Bash
#!/bin/bash
|
|
# Install / re-install the Overlord Agent host-side service.
|
|
#
|
|
# Run as user `erik` from /home/erik/MosswartOverlord:
|
|
# bash agent/install.sh
|
|
#
|
|
# Requires sudo for the systemd parts (you'll be prompted once).
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_DIR="/home/erik/MosswartOverlord"
|
|
AGENT_DIR="$REPO_DIR/agent"
|
|
VENV_DIR="$AGENT_DIR/.venv"
|
|
SERVICE_FILE="$AGENT_DIR/overlord-agent.service"
|
|
SYSTEMD_TARGET="/etc/systemd/system/overlord-agent.service"
|
|
|
|
if [[ "$(pwd)" != "$REPO_DIR" ]]; then
|
|
echo "Run from $REPO_DIR (currently in $(pwd))" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> Creating/updating venv at $VENV_DIR"
|
|
if [[ ! -d "$VENV_DIR" ]]; then
|
|
python3 -m venv "$VENV_DIR"
|
|
fi
|
|
"$VENV_DIR/bin/pip" install --quiet --upgrade pip
|
|
"$VENV_DIR/bin/pip" install --quiet -r "$AGENT_DIR/requirements.txt"
|
|
|
|
echo "==> Installing systemd unit"
|
|
sudo cp "$SERVICE_FILE" "$SYSTEMD_TARGET"
|
|
sudo systemctl daemon-reload
|
|
|
|
echo "==> Enabling + starting overlord-agent"
|
|
sudo systemctl enable overlord-agent
|
|
sudo systemctl restart overlord-agent
|
|
|
|
sleep 1
|
|
echo "==> Status:"
|
|
sudo systemctl --no-pager status overlord-agent | head -15
|
|
|
|
echo ""
|
|
echo "==> Smoke test:"
|
|
curl -s http://127.0.0.1:8767/agent/health | python3 -m json.tool || true
|
|
|
|
echo ""
|
|
echo "Done. Logs: journalctl -u overlord-agent -f"
|