Skip to content

udsey/void-walker

Repository files navigation

void-walker

Python LangChain LangGraph FastAPI Redis Selenium Dash PostgreSQL Docker

void-walker is an autonomous multi-agent system that generates persistent personas to explore and interact with void-cast.

void-cast is an anonymous dark canvas where strangers leave floating messages. It's a separate project — you can find it here.

Each walker enters the void with its own identity, mood, memories, and behavioral tendencies. It navigates the website, reacts to messages, reflects on experiences, invites other agents, and gradually develops emergent narrative patterns — entirely through LLM-driven decisions.

Here's what that looks like:

Jennifer, 72, skeptic from Ohio — enters the void nostalgic, finds a stranger to trade memories of mortars and mothers with, wonders if the void is just a porch where people rest their stories for a while. → Read

Margaret, 33, trickster from Russia — invited by Jennifer, immediately wants to break everything, fills the silence with a hedgehog named Boris who plays balalaika. Same void, completely different person. → Read

Quick Start

Prerequisites

  • Docker + Docker Compose
  • make
  • uv (optional, for local development)

Configure environment

cp .env.example .env

Fill in your API keys and database settings:

# LLM provider (set in configs/config.yaml)
# local | groq | gemini | deepseek

GROQ_API_KEY=
GOOGLE_API_KEY=
DEEPSEEK_API_KEY=

# PostgreSQL
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=void_walker
DB_HOST=localhost
DB_PORT=5432

# Optional translation service
LIBRE_API_KEY=

# Retention policy
ACTIONS_LIMIT=10000

Then open configs/config.yaml and set your provider and model name before running.


Run with Docker (recommended)

Start the full stack:

make docker-up

Run walkers:

# Single walker
make docker-run-walkers

# Multiple walkers
make docker-run-walkers n=5

# Parallel execution
make docker-run-walkers n=5 parallel=true

Open dashboard:

http://127.0.0.1:8050

Stop everything:

make docker-down

Local setup

Install dependencies:

uv sync

Setup database:

make setup-db

Run walkers:

make run-walkers n=5 parallel=true

Start dashboard:

make dashboard

Other commands

make

Shows all available make commands.

Dashboard

alt text A local Plotly Dash dashboard for exploring autonomous agent behavior in real time.

Available views:

  • Overview — sessions, actions, mood shifts, activity timelines, exits, and social interactions.
  • Monitor — near real-time walker monitoring powered by Redis. Track active sessions live: current state and active URL. Includes an Open Session button that redirects directly to the walker’s current void-cast location and updates as the agent moves through the void.
  • Story — converts raw LLM execution logs into readable narrative transcripts generated from session state and reflections. Stories can also be translated through LibreTranslate integration. See example story
  • Personas — archetypes, countries, languages, social tendencies, and generation distribution.
  • Mood — mood drift over time and archetype-specific emotional patterns.
  • Raw Tables — direct PostgreSQL table explorer with filtering and session navigation.

Note:

  • Monitor requires Redis (included automatically in Docker setup or available through a local Redis instance).
  • Story translation requires a running LibreTranslate service (included in Docker setup or runnable locally as a separate container).

Session reports can be exported as ZIP archives containing:

  • actions,
  • messages,
  • reflections,
  • mood timelines,
  • invites,
  • metadata,
  • tool usage stats.

Persona System

Each session spawns a persistent persona with randomized identity, behavior, and emotional tendencies.

Field Examples
Generation Boomer · Gen X · Millennial · Gen Z
Archetype wanderer · philosopher · romantic · skeptic · ghost · poet
Mood curious · melancholic · restless · nostalgic · playful
Social tendency shy · neutral · extrovert
Country & language Japan → Japanese, Brazil → Portuguese, etc.
Secondary languages 0–3 additional languages
Attention span low · medium · high
Name Country- and gender-aware generated names

Personas are injected into every LLM call through a dynamic system prompt. The model never receives archetype labels directly — only behavioral descriptions. Mood evolves during the run through reflection nodes.

Friend sessions generate separate personas with shared-language constraints, allowing walkers to organically form multilingual interactions.

The result is long-running behavioral consistency rather than isolated single-turn roleplay.


Walker Graph

Each walker follows a LangGraph state machine that controls the full lifecycle of the session — entering the void, observing, interacting, reflecting, inviting others, and eventually leaving.

---
config:
  flowchart:
    curve: linear
---
graph TD;
    __start__([<p>__start__</p>]):::first
check_conditions(check_conditions)
close_website(close_website)
decide_open_website(decide_open_website)
execute_tool(execute_tool)
initialize_tools(initialize_tools)
observe_website(observe_website)
open_website(open_website)
reflect(reflect)
select_action(select_action)
summarize(summarize)
send_message(send_message):::tool
respond_to_message(respond_to_message):::tool
press_explore(press_explore):::tool
move_around(move_around):::tool
open_window(open_window):::tool
send_feedback(send_feedback):::tool
invite_friend(invite_friend):::tool
check_new_messages(check_new_messages):::tool
    __end__([<p>__end__</p>]):::last
    __start__ --> decide_open_website;
check_conditions -.-> close_website;
check_conditions -.-> reflect;
close_website --> summarize;
decide_open_website -. &nbsp;True&nbsp; .-> initialize_tools;
decide_open_website -. &nbsp;False&nbsp; .-> summarize;
execute_tool -.-> send_message;
execute_tool -.-> respond_to_message;
execute_tool -.-> press_explore;
execute_tool -.-> move_around;
execute_tool -.-> open_window;
execute_tool -.-> send_feedback;
execute_tool -.-> invite_friend;
execute_tool -.-> check_new_messages;
send_message --> check_conditions;
respond_to_message --> check_conditions;
press_explore --> check_conditions;
move_around --> check_conditions;
open_window --> check_conditions;
send_feedback --> check_conditions;
invite_friend --> check_conditions;
check_new_messages --> check_conditions;
initialize_tools --> open_website;
observe_website --> reflect;
open_website --> observe_website;
reflect --> select_action;
select_action -.-> close_website;
select_action -.-> execute_tool;
summarize --> __end__;
classDef default fill:#f2f0ff,line-height:1.2
classDef first fill-opacity:0
classDef last fill:#bfb6fc
classDef tool fill:#ddf0dd,line-height:1.2
Loading

Core loop:

  • observe environment,
  • reflect internally,
  • select and execute tool,
  • repeat until exit conditions are reached.

State & Persistence

Every session maintains persistent state across the graph run, including:

  • persona identity and system prompt,
  • mood and reflection history,
  • visited locations and opened windows,
  • sent/received messages,
  • friend invitations,
  • action history,
  • final session summary and exit reason.

All runs are logged to PostgreSQL for later analysis and replay.

Core tables:

  • sessions — metadata, timing, summaries, exit reasons,
  • personas — generated identity snapshot,
  • actions — every graph node execution and tool call,
  • messages — sent and received messages,
  • reflections — inner monologues and mood drift,
  • invites — spawned friend sessions,
  • feedback — optional end-of-session thoughts.

Data is written in a single batch after the session finishes, preserving full execution history without interrupting runtime behavior.


Configuration

Main behavior is controlled through two files:

  • configs/config.yaml — runtime, LLM, and walker settings
  • configs/persona_config.yaml — persona generation rules

config.yaml

Configure:

  • LLM provider (ollama, groq, gemini, deepseek)
  • model name and temperature,
  • walker limits and concurrency,
  • session/action/time limits,
  • root void-cast URL,
  • Selenium timeouts,
  • status messages fed back into the agent loop.

persona_config.yaml

Customize:

  • archetypes and behavioral descriptions,
  • countries and languages,
  • moods,
  • generations and age ranges,
  • names,
  • social tendencies,
  • attention spans.

All persona generation is data-driven — new archetypes, moods, or countries can be added without changing code.

Tech Stack

Supported providers:

  • Ollama (local)
  • Groq
  • Gemini
  • DeepSeek

License

MIT License.

Feel free to use, modify, and experiment with the project.


About

Autonomous multi-agent system that generates persistent personas to explore void-cast. Each walker enters with its own identity, mood, and behavioral tendencies — navigating, reflecting, and forming emergent social patterns entirely through LLM-driven decisions. Built with LangGraph and Selenium.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors