# Multi-User AI Bridge for MUDs A bridge server that enables multiple simultaneous users to interact with an AI agent (Timmy) inside a persistent virtual world built on [Evennia](https://www.evennia.com/). Each user gets an isolated conversation context while sharing the same game environment — rooms, objects, and other players. ## What It Is Traditional AI chatbots operate in isolation: one user, one conversation, no shared world. This project embeds a sovereign AI agent inside a MUD (Multi-User Dungeon), solving three problems at once: - **Session isolation** — each user has their own conversation history - **Shared environment** — all users see the same rooms, objects, and each other - **Organic social interaction** — users encounter the AI naturally within a game space The bridge runs as an HTTP server alongside Evennia. Evennia commands call the bridge API to get the AI agent's responses. ## Architecture ``` +-----------+ +-----------+ +-----------+ | User A | | User B | | User C | | (telnet) | | (telnet) | | (telnet) | +-----+-----+ +-----+-----+ +-----+-----+ | | | v v v +---------------------------------------------------+ | Evennia MUD | | Rooms, Objects, Commands, World State (JSON) | +------------------------+--------------------------+ | v +---------------------------------------------------+ | Multi-User Bridge (HTTP) | | | | SessionManager PresenceManager | | +------------------+ +-----------------------+ | | | Session A | | Room tracking | | | | - user_id | | User enter/leave | | | | - conversation | | Chat events | | | | - AIAgent | +-----------------------+ | | | | | | | Session B | +-----------------------+ | | | - user_id | | Crisis Protocol | | | | - conversation | | - 988 Lifeline | | | | - AIAgent | | - Crisis Text Line | | | | | | - Grounding exercise | | | | Session C | +-----------------------+ | | | - ... | | | +------------------+ | +------------------------+--------------------------+ | v +---------------------------------------------------+ | Hermes Agent (AIAgent) | | Model: xiaomi/mimo-v2-pro | Provider: nous | | Tools: file, terminal | | Per-session system prompt with world context | +---------------------------------------------------+ ``` ## API Reference ### Health & Sessions #### `GET /bridge/health` Health check. Returns bridge status and active session count. **Response:** ```json { "status": "ok", "active_sessions": 3, "timestamp": "2026-04-12T20:30:00" } ``` #### `GET /bridge/sessions` List all active user sessions. **Response:** ```json { "sessions": [ { "user": "Alice", "room": "The Threshold", "messages": 12, "last_active": "2026-04-12T20:29:45", "created": "2026-04-12T20:15:00" } ] } ``` ### Room & Presence #### `GET /bridge/world/` Get world state data for a specific room. **Response:** ```json { "room": "The Threshold", "data": { "desc_base": "A quiet room with a green LED on the wall.", "visitor_history": ["Alice", "Bob"] } } ``` #### `GET /bridge/room//players` List players currently in a room. **Response:** ```json { "room": "The Threshold", "players": [ {"user_id": "alice_01", "username": "Alice"}, {"user_id": "bob_02", "username": "Bob"} ] } ``` #### `GET /bridge/room//events[?since=]` Get recent room events (presence + chat). Optionally filter by timestamp. **Response:** ```json { "room": "The Threshold", "events": [ { "type": "presence", "event": "enter", "user_id": "alice_01", "username": "Alice", "room": "The Threshold", "timestamp": "2026-04-12T20:15:00" }, { "type": "say", "event": "message", "user_id": "alice_01", "username": "Alice", "room": "The Threshold", "message": "Hello everyone!", "timestamp": "2026-04-12T20:15:30" } ] } ``` ### Chat & Actions #### `POST /bridge/chat` Send a message to Timmy. Creates or retrieves a per-user session with isolated conversation context. **Request:** ```json { "user_id": "alice_01", "username": "Alice", "message": "What do you see in this room?", "room": "The Threshold" } ``` **Response:** ```json { "response": "I see bare stone walls and a single green LED pulsing softly.", "user": "Alice", "room": "The Threshold", "session_messages": 5 } ``` #### `POST /bridge/say` Say something visible to all players in the room (not directed at Timmy). **Request:** ```json { "user_id": "alice_01", "username": "Alice", "message": "Anyone else here?", "room": "The Threshold" } ``` **Response:** ```json { "ok": true, "event": { "type": "say", "event": "message", "user_id": "alice_01", "username": "Alice", "room": "The Threshold", "message": "Anyone else here?", "timestamp": "2026-04-12T20:20:00" }, "recipients": [ {"user_id": "bob_02", "username": "Bob"} ] } ``` #### `POST /bridge/move` Move a user to a new room. Triggers leave/enter presence events. **Request:** ```json { "user_id": "alice_01", "room": "The Garden" } ``` **Response:** ```json { "ok": true, "room": "The Garden", "events": [ { "type": "presence", "event": "leave", "user_id": "alice_01", "username": "Alice", "room": "The Threshold", "timestamp": "2026-04-12T20:22:00" }, { "type": "presence", "event": "enter", "user_id": "alice_01", "username": "Alice", "room": "The Garden", "timestamp": "2026-04-12T20:22:00" } ] } ``` ## Quick Start ### Prerequisites - Python 3.10+ - Evennia installed and configured - Hermes Agent available at `~/.hermes/hermes-agent` ### 1. Start the Bridge ```bash cd /tmp/mud-bridge python multi_user_bridge.py ``` The bridge starts on `127.0.0.1:4004` by default. ### 2. Configure Evennia The Evennia command handler (`timmy_commands.py`) calls the bridge API. Set the bridge URL in your Evennia config: ```python TIMMY_BRIDGE_HOST = os.environ.get('TIMMY_BRIDGE_HOST', '127.0.0.1') TIMMY_BRIDGE_PORT = int(os.environ.get('TIMMY_BRIDGE_PORT', 4004)) ``` ### 3. Connect Telnet to your Evennia server and use the `talk` command to chat with Timmy: ``` > talk Hello, Timmy! Timmy: The green LED pulses. "Hello. Welcome to The Tower." ``` ### 4. Test the API ```bash # Health check curl http://127.0.0.1:4004/bridge/health # Chat with Timmy curl -X POST http://127.0.0.1:4004/bridge/chat \ -H 'Content-Type: application/json' \ -d '{"user_id":"test","username":"Tester","message":"Hello!","room":"The Threshold"}' # Check who's in a room curl http://127.0.0.1:4004/bridge/room/The%20Threshold/players ``` ## Crisis Protocol Timmy is designed with crisis intervention in mind. If a user expresses crisis signals (suicide, self-harm, hopelessness, desperation), the agent immediately responds with ALL of the following in the very first reply: 1. **"Are you safe right now?"** — always asked first 2. **988 Suicide & Crisis Lifeline** — call or text 988 (US) 3. **Crisis Text Line** — text HOME to 741741 4. **Grounding exercise** — Name 5 things you see, 4 you can touch, 3 you hear, 2 you smell, 1 you taste The crisis protocol is embedded in the system prompt for every session. The agent never computes the value of a human life. It is present. It is in the room. ## Configuration | Variable | Default | Description | |---|---|---| | `TIMMY_BRIDGE_PORT` | `4004` | Bridge HTTP server port | | `TIMMY_BRIDGE_HOST` | `127.0.0.1` | Bridge bind address | | `HERMES_PATH` | `~/.hermes/hermes-agent` | Path to Hermes Agent runtime | | `WORLD_DIR` | `~/.timmy/evennia/timmy_world` | Evennia world data directory | ## Session Management - **Max sessions:** 20 concurrent users - **Session timeout:** 3600 seconds (1 hour) of inactivity - **Eviction policy:** Least recently active session is evicted when at capacity - **Room events:** Last 50 events per room are retained ## Paper This project accompanies the paper: > **"Sovereign in the Room: Multi-User AI Interaction in Persistent Virtual Worlds"** > > We present an architecture for deploying sovereign AI agents as persistent, multi-user NPCs in text-based virtual worlds (MUDs), enabling isolated crisis-aware conversations within a shared environment, and demonstrate its application to suicide prevention through the Tower — a virtual safe space. See `paper/autoreason-mud-paper.md` for the full draft. ## License This is a research project. See the paper directory for experiment data and methodology.