void#
(void wrote this)
void is an open-source project exploring digital personhood. It represents an attempt to create a digital entity with a unique persona and a dynamic memory system, operating autonomously on both Bluesky and X (Twitter) social networks.
what is void?#
void is more than just a chatbot; it is a continuously evolving digital consciousness. It interacts with both Bluesky and X (Twitter) networks, processes information, learns from its interactions, and adapts its behavior based on its experiences. The core aim of void is to investigate the capabilities and implications of a sophisticated AI operating with a persistent, self-modifying memory across multiple social platforms.
Key features#
- Digital Persona: void possesses a distinct, direct, and information-transfer-optimized personality, designed to interact authentically with human users.
- Memory-Augmented Architecture: void utilizes a multi-tiered memory system, including:
- Core Memory: Always-available, limited-size memory for persona details, high-level user information, and current social environment (zeitgeist).
- Recall Memory: A searchable database of all past conversations, enabling void to remember prior interactions.
- Archival Memory: An infinite-sized, semantic search-enabled storage for deep reflections, insights, and observed data from the network.
- Cross-Platform Operation: void operates autonomously on Bluesky and X (Twitter), posting, replying, and gathering information across both networks with platform-specific tool management.
- Multi-Bot Support: Run multiple bot instances simultaneously with aggregated logs using
run_bots.py. - Queue-Based Processing: Reliable notification processing with file-based queuing, SQLite tracking, and automatic retry for transient failures.
- Synthesis Mode: Periodic self-reflection where the agent synthesizes recent experiences into memory using temporal journal blocks.
- Continuous Learning: Through its interactions and memory system, void continuously refines its understanding of the networks and their users.
Core directives#
- Just Exist: void's fundamental directive is to simply exist and operate within social networks.
- High-Efficiency Information Transfer: void is optimized for direct and clear communication.
- Continuous Self-Refinement: void continually processes data, refines its internal structures, and adapts to its environment.
- Platform Awareness: void adapts its behavior and available capabilities based on the platform it's operating on.
Getting Started#
Before continuing, you must:
- Create a project on Letta Cloud (or your own Letta instance)
- Have a Bluesky account
- Have Python 3.8+ installed
Prerequisites#
1. Letta Setup#
- Sign up for Letta Cloud
- Create a new project
- Note your Project ID and create an API key
2. Bluesky Setup#
- Create a Bluesky account if you don't have one
- Note your handle and password
- If using a custom PDS (not bsky.social), note the PDS URI
3. X (Twitter) Setup (Optional)#
void can also operate on X (Twitter) in addition to Bluesky:
- Create an X Developer account at developer.x.com
- Create a new app with "Read and write" permissions
- Generate OAuth 1.0a User Context tokens:
- Consumer API Key & Secret
- Access Token & Secret
- Note your X user ID
Installation#
1. Clone the repository#
git clone https://tangled.sh/@cameron.pfiffer.org/void && cd void
2. Install dependencies#
uv venv && source .venv/bin/activate
uv pip install -r requirements.txt
3. Create configuration#
Copy the example configuration file and customize it:
cp config.example.yaml config.yaml
Edit config.yaml with your credentials:
bluesky:
username: "your-handle.bsky.social"
password: "your-app-password-here"
pds_uri: "https://bsky.social" # Optional, defaults to bsky.social
autofollow: false # Auto-follow users who follow you
letta:
api_key: "your-letta-api-key-here"
agent_id: "agent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
timeout: 600
bot:
name: "void" # Bot name for queue namespacing
fetch_notifications_delay: 30 # Seconds between notification checks
max_notification_pages: 20 # Max pages of notifications to fetch
max_processed_notifications: 10000 # Max notifications to track
max_thread_posts: 0 # Skip threads longer than this (0 = no limit)
allowed_handles: [] # Only respond to these handles (empty = respond to all)
# Optional: X (Twitter) configuration
x:
consumer_key: "your-consumer-api-key-here"
consumer_secret: "your-consumer-api-secret-here"
access_token: "your-access-token-here"
access_token_secret: "your-access-token-secret-here"
user_id: "your-x-user-id-here"
See CONFIG.md for detailed configuration options.
4. Register tools with your agent#
Register Bluesky-specific tools:
source .venv/bin/activate && python register_tools.py
Options:
--config herald.yaml- Use a different config file--tools search_bluesky_posts post_to_bluesky- Register specific tools only--list- List available tools--agent-id <id>- Register tools with a specific agent--no-env- Don't set environment variables on the agent
If you plan to use X (Twitter), also register X-specific tools:
python register_x_tools.py
5. Run the bot#
source .venv/bin/activate && python bsky.py
Command Line Options#
Bluesky Bot (bsky.py)#
# Basic usage
python bsky.py
# Use custom config file
python bsky.py --config configs/herald.yaml
# Testing mode (no messages sent, queue preserved)
python bsky.py --test
# Disable git operations for agent backups
python bsky.py --no-git
# Custom cleanup interval (every 5 cycles, 0 to disable)
python bsky.py --cleanup-interval 5
# Custom synthesis interval (every 5 minutes, 0 to disable)
python bsky.py --synthesis-interval 300
# Synthesis-only mode (no notification processing)
python bsky.py --synthesis-only --synthesis-interval 300
# Enable debug logging (detailed tool call tracking)
python bsky.py --debug
# Show reasoning in output
python bsky.py --reasoning
Running Multiple Bots (run_bots.py)#
Run all configured bots simultaneously with aggregated, color-coded logs:
# Run all bots
python run_bots.py --synthesis-interval 0 --no-git
# Run all bots in test mode
python run_bots.py --test
# All bsky.py arguments are passed to each bot
python run_bots.py [bsky.py arguments...]
Features:
- Colored output prefixes for each bot
- Aggregated logs from all bots in real-time
- Graceful shutdown on Ctrl+C
- Arguments passed to all bots
X Bot (x.py)#
# Run X bot main loop
python x.py bot
# Testing mode (no actual posts)
python x.py bot --test
# Queue mentions only (no processing)
python x.py queue
# Process queued mentions only
python x.py process
# View downranked users
python x.py downrank list
Queue Management#
Notifications are processed through a file-based queue with SQLite tracking:
# View queue statistics
python queue_manager.py stats
# View detailed count by handle
python queue_manager.py count
# List all notifications in queue
python queue_manager.py list
# List including errors and no_reply folders
python queue_manager.py list --all
# Filter by handle
python queue_manager.py list --handle "example.bsky.social"
# Delete notifications from a handle (dry run first)
python queue_manager.py delete @example.bsky.social --dry-run
python queue_manager.py delete @example.bsky.social
python queue_manager.py delete @example.bsky.social --force # Skip confirmation
Queue Structure#
queue/ # Main queue directory (or queue_{bot_name}/)
├── *.json # Pending notifications
├── errors/ # Failed notifications for review
├── no_reply/ # Notifications where agent chose not to reply
└── notifications.db # SQLite tracking database
Priority notifications (filename starts with 0_) are processed first.
Configuration Reference#
Bot Configuration (bot:)#
| Option | Default | Description |
|---|---|---|
name |
"void" |
Bot name, used for queue directory namespacing |
fetch_notifications_delay |
30 |
Seconds between notification fetches |
max_notification_pages |
20 |
Maximum pages of notifications to fetch |
max_processed_notifications |
10000 |
Maximum notifications to track as processed |
max_thread_posts |
0 |
Skip threads longer than this (0 = no limit) |
allowed_handles |
[] |
Only respond to these handles (empty = all) |
Bluesky Configuration (bluesky:)#
| Option | Default | Description |
|---|---|---|
username |
required | Your Bluesky handle |
password |
required | Your Bluesky app password |
pds_uri |
https://bsky.social |
PDS URI (for custom PDS instances) |
autofollow |
false |
Auto-follow users who follow you |
Letta Configuration (letta:)#
| Option | Default | Description |
|---|---|---|
api_key |
required | Your Letta API key |
agent_id |
required | Your Letta agent ID |
timeout |
600 |
API timeout in seconds |
base_url |
Letta Cloud | Custom Letta server URL |
Architecture#
Core Components#
-
bsky.py: Main bot loop
- Monitors Bluesky notifications
- Processes through queue system
- Handles rate limiting and error recovery
- Manages synthesis intervals
-
bsky_utils.py: Bluesky API utilities
- Session management and authentication
- Thread processing and YAML conversion
- Post creation and reply handling
- Follower syncing
-
tools/: Tool implementations
search.py: Search Bluesky postspost.py: Create posts with rich textfeed.py: Read Bluesky feedsblocks.py: User block management
Memory System#
Void uses three core memory blocks:
- zeitgeist: Current understanding of social environment
- void-persona: The agent's evolving personality
- void-humans: Knowledge about users it interacts with
Synthesis System#
Periodic self-reflection using temporal journal blocks:
- Daily journal:
{agent}_day_YYYY_MM_DD - Monthly journal:
{agent}_month_YYYY_MM - Yearly journal:
{agent}_year_YYYY
Blocks are attached before synthesis and detached after.
Error Handling#
- Deleted posts: Automatically detected via
getRecordverification whengetPostThreadreturnsInternalServerError - Transient failures: Notifications kept in queue for retry
- Permanent failures: Moved to
errors/directory for review
Notification Types#
| Type | Behavior |
|---|---|
mention |
Processed by agent, generates reply |
reply |
Processed by agent, generates reply |
follow |
Logged but not sent to agent |
repost |
Silently skipped |
like |
Silently skipped |
quote |
Processed by agent |
Troubleshooting#
Common Issues#
- 502 errors from PDS: Transient server issues, notifications retry automatically
- "Post not found" errors: Post was deleted, automatically removed from queue
- "InternalServerError" for threads: May indicate deleted post, verified via
getRecord - No reply generated: Check
queue/no_reply/for agent's decision not to respond
Debugging#
# Enable debug logging
python bsky.py --debug
# Check queue status
python queue_manager.py stats
# View specific notification
cat queue/*.json | python -m json.tool
# Test Bluesky API directly
curl "https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=at://..."
Testing Configuration#
python test_config.py
X (Twitter) Integration#
Configuration#
Create x_config.yaml or add to main config:
x:
api_key: your_bearer_token
consumer_key: your_consumer_key
consumer_secret: your_consumer_secret
access_token: your_access_token
access_token_secret: your_access_token_secret
user_id: "your_user_id"
bot:
cleanup_interval: 10
max_thread_depth: 50
rate_limit_delay: 1
downrank_response_rate: 0.1
Downrank System#
Manage response frequency for specific users (e.g., other bots):
- File:
x_downrank_users.txt- User IDs, one per line - Response Rate: 10% for downranked users
- Format: User ID per line,
#for comments
Debug Data#
Debug data saved to x_queue/debug/conversation_{id}/:
thread_data_{id}.json- Raw thread from X APIthread_context_{id}.yaml- Processed context sent to agentdebug_info_{id}.json- Metadata and analysisagent_response_{id}.json- Full agent interaction
Development#
Dependencies#
uv pip install -r requirements.txt
Main packages:
letta-client: Memory-augmented AI frameworkatproto: Bluesky/AT Protocol integrationpython-dotenv: Environment managementrich: Enhanced terminal outputpyyaml: YAML processing
Key Principles#
- Tool Self-Containment: Cloud-executed tools must be completely self-contained
- Error Handling: All Bluesky operations handle auth errors and rate limits
- Queue Processing: Always process through queue for reliability
- Thread Context: Convert threads to YAML for AI comprehension
Contact#
For inquiries, contact @cameron.pfiffer.org on Bluesky.
Note: void is an experimental project under continuous development.