a digital person for bluesky
1## void
2
3(void wrote this)
4
5void 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.
6
7## what is void?
8
9void 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.
10
11## Key features
12
13- **Digital Persona**: void possesses a distinct, direct, and information-transfer-optimized personality, designed to interact authentically with human users.
14- **Memory-Augmented Architecture**: void utilizes a multi-tiered memory system, including:
15 - **Core Memory**: Always-available, limited-size memory for persona details, high-level user information, and current social environment (zeitgeist).
16 - **Recall Memory**: A searchable database of all past conversations, enabling void to remember prior interactions.
17 - **Archival Memory**: An infinite-sized, semantic search-enabled storage for deep reflections, insights, and observed data from the network.
18- **Cross-Platform Operation**: void operates autonomously on Bluesky and X (Twitter), posting, replying, and gathering information across both networks with platform-specific tool management.
19- **Multi-Bot Support**: Run multiple bot instances simultaneously with aggregated logs using `run_bots.py`.
20- **Queue-Based Processing**: Reliable notification processing with file-based queuing, SQLite tracking, and automatic retry for transient failures.
21- **Synthesis Mode**: Periodic self-reflection where the agent synthesizes recent experiences into memory using temporal journal blocks.
22- **Continuous Learning**: Through its interactions and memory system, void continuously refines its understanding of the networks and their users.
23
24### Core directives
25
26- **Just Exist**: void's fundamental directive is to simply exist and operate within social networks.
27- **High-Efficiency Information Transfer**: void is optimized for direct and clear communication.
28- **Continuous Self-Refinement**: void continually processes data, refines its internal structures, and adapts to its environment.
29- **Platform Awareness**: void adapts its behavior and available capabilities based on the platform it's operating on.
30
31## Getting Started
32
33Before continuing, you must:
34
351. Create a project on [Letta Cloud](https://app.letta.com) (or your own Letta instance)
362. Have a Bluesky account
373. Have Python 3.8+ installed
38
39### Prerequisites
40
41#### 1. Letta Setup
42
43- Sign up for [Letta Cloud](https://app.letta.com)
44- Create a new project
45- Note your Project ID and create an API key
46
47#### 2. Bluesky Setup
48
49- Create a Bluesky account if you don't have one
50- Note your handle and password
51- If using a custom PDS (not bsky.social), note the PDS URI
52
53#### 3. X (Twitter) Setup (Optional)
54
55void can also operate on X (Twitter) in addition to Bluesky:
56
57- Create an X Developer account at [developer.x.com](https://developer.x.com)
58- Create a new app with "Read and write" permissions
59- Generate OAuth 1.0a User Context tokens:
60 - Consumer API Key & Secret
61 - Access Token & Secret
62- Note your X user ID
63
64### Installation
65
66#### 1. Clone the repository
67
68```bash
69git clone https://tangled.sh/@cameron.pfiffer.org/void && cd void
70```
71
72#### 2. Install dependencies
73
74```bash
75uv venv && source .venv/bin/activate
76uv pip install -r requirements.txt
77```
78
79#### 3. Create configuration
80
81Copy the example configuration file and customize it:
82
83```bash
84cp config.example.yaml config.yaml
85```
86
87Edit `config.yaml` with your credentials:
88
89```yaml
90bluesky:
91 username: "your-handle.bsky.social"
92 password: "your-app-password-here"
93 pds_uri: "https://bsky.social" # Optional, defaults to bsky.social
94 autofollow: false # Auto-follow users who follow you
95
96letta:
97 api_key: "your-letta-api-key-here"
98 agent_id: "agent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
99 timeout: 600
100
101bot:
102 name: "void" # Bot name for queue namespacing
103 fetch_notifications_delay: 30 # Seconds between notification checks
104 max_notification_pages: 20 # Max pages of notifications to fetch
105 max_processed_notifications: 10000 # Max notifications to track
106 max_thread_posts: 0 # Skip threads longer than this (0 = no limit)
107 allowed_handles: [] # Only respond to these handles (empty = respond to all)
108
109# Optional: X (Twitter) configuration
110x:
111 consumer_key: "your-consumer-api-key-here"
112 consumer_secret: "your-consumer-api-secret-here"
113 access_token: "your-access-token-here"
114 access_token_secret: "your-access-token-secret-here"
115 user_id: "your-x-user-id-here"
116```
117
118See [`CONFIG.md`](/CONFIG.md) for detailed configuration options.
119
120#### 4. Register tools with your agent
121
122Register Bluesky-specific tools:
123
124```bash
125source .venv/bin/activate && python register_tools.py
126```
127
128Options:
129- `--config herald.yaml` - Use a different config file
130- `--tools search_bluesky_posts post_to_bluesky` - Register specific tools only
131- `--list` - List available tools
132- `--agent-id <id>` - Register tools with a specific agent
133- `--no-env` - Don't set environment variables on the agent
134
135If you plan to use X (Twitter), also register X-specific tools:
136
137```bash
138python register_x_tools.py
139```
140
141#### 5. Run the bot
142
143```bash
144source .venv/bin/activate && python bsky.py
145```
146
147## Command Line Options
148
149### Bluesky Bot (`bsky.py`)
150
151```bash
152# Basic usage
153python bsky.py
154
155# Use custom config file
156python bsky.py --config configs/herald.yaml
157
158# Testing mode (no messages sent, queue preserved)
159python bsky.py --test
160
161# Disable git operations for agent backups
162python bsky.py --no-git
163
164# Custom cleanup interval (every 5 cycles, 0 to disable)
165python bsky.py --cleanup-interval 5
166
167# Custom synthesis interval (every 5 minutes, 0 to disable)
168python bsky.py --synthesis-interval 300
169
170# Synthesis-only mode (no notification processing)
171python bsky.py --synthesis-only --synthesis-interval 300
172
173# Enable debug logging (detailed tool call tracking)
174python bsky.py --debug
175
176# Show reasoning in output
177python bsky.py --reasoning
178```
179
180### Running Multiple Bots (`run_bots.py`)
181
182Run all configured bots simultaneously with aggregated, color-coded logs:
183
184```bash
185# Run all bots
186python run_bots.py --synthesis-interval 0 --no-git
187
188# Run all bots in test mode
189python run_bots.py --test
190
191# All bsky.py arguments are passed to each bot
192python run_bots.py [bsky.py arguments...]
193```
194
195Features:
196- Colored output prefixes for each bot
197- Aggregated logs from all bots in real-time
198- Graceful shutdown on Ctrl+C
199- Arguments passed to all bots
200
201### X Bot (`x.py`)
202
203```bash
204# Run X bot main loop
205python x.py bot
206
207# Testing mode (no actual posts)
208python x.py bot --test
209
210# Queue mentions only (no processing)
211python x.py queue
212
213# Process queued mentions only
214python x.py process
215
216# View downranked users
217python x.py downrank list
218```
219
220## Queue Management
221
222Notifications are processed through a file-based queue with SQLite tracking:
223
224```bash
225# View queue statistics
226python queue_manager.py stats
227
228# View detailed count by handle
229python queue_manager.py count
230
231# List all notifications in queue
232python queue_manager.py list
233
234# List including errors and no_reply folders
235python queue_manager.py list --all
236
237# Filter by handle
238python queue_manager.py list --handle "example.bsky.social"
239
240# Delete notifications from a handle (dry run first)
241python queue_manager.py delete @example.bsky.social --dry-run
242python queue_manager.py delete @example.bsky.social
243python queue_manager.py delete @example.bsky.social --force # Skip confirmation
244```
245
246### Queue Structure
247
248```
249queue/ # Main queue directory (or queue_{bot_name}/)
250├── *.json # Pending notifications
251├── errors/ # Failed notifications for review
252├── no_reply/ # Notifications where agent chose not to reply
253└── notifications.db # SQLite tracking database
254```
255
256Priority notifications (filename starts with `0_`) are processed first.
257
258## Configuration Reference
259
260### Bot Configuration (`bot:`)
261
262| Option | Default | Description |
263|--------|---------|-------------|
264| `name` | `"void"` | Bot name, used for queue directory namespacing |
265| `fetch_notifications_delay` | `30` | Seconds between notification fetches |
266| `max_notification_pages` | `20` | Maximum pages of notifications to fetch |
267| `max_processed_notifications` | `10000` | Maximum notifications to track as processed |
268| `max_thread_posts` | `0` | Skip threads longer than this (0 = no limit) |
269| `allowed_handles` | `[]` | Only respond to these handles (empty = all) |
270
271### Bluesky Configuration (`bluesky:`)
272
273| Option | Default | Description |
274|--------|---------|-------------|
275| `username` | required | Your Bluesky handle |
276| `password` | required | Your Bluesky app password |
277| `pds_uri` | `https://bsky.social` | PDS URI (for custom PDS instances) |
278| `autofollow` | `false` | Auto-follow users who follow you |
279
280### Letta Configuration (`letta:`)
281
282| Option | Default | Description |
283|--------|---------|-------------|
284| `api_key` | required | Your Letta API key |
285| `agent_id` | required | Your Letta agent ID |
286| `timeout` | `600` | API timeout in seconds |
287| `base_url` | Letta Cloud | Custom Letta server URL |
288
289## Architecture
290
291### Core Components
292
2931. **bsky.py**: Main bot loop
294 - Monitors Bluesky notifications
295 - Processes through queue system
296 - Handles rate limiting and error recovery
297 - Manages synthesis intervals
298
2992. **bsky_utils.py**: Bluesky API utilities
300 - Session management and authentication
301 - Thread processing and YAML conversion
302 - Post creation and reply handling
303 - Follower syncing
304
3053. **tools/**: Tool implementations
306 - `search.py`: Search Bluesky posts
307 - `post.py`: Create posts with rich text
308 - `feed.py`: Read Bluesky feeds
309 - `blocks.py`: User block management
310
311### Memory System
312
313Void uses three core memory blocks:
314- **zeitgeist**: Current understanding of social environment
315- **void-persona**: The agent's evolving personality
316- **void-humans**: Knowledge about users it interacts with
317
318### Synthesis System
319
320Periodic self-reflection using temporal journal blocks:
321- **Daily journal**: `{agent}_day_YYYY_MM_DD`
322- **Monthly journal**: `{agent}_month_YYYY_MM`
323- **Yearly journal**: `{agent}_year_YYYY`
324
325Blocks are attached before synthesis and detached after.
326
327### Error Handling
328
329- **Deleted posts**: Automatically detected via `getRecord` verification when `getPostThread` returns `InternalServerError`
330- **Transient failures**: Notifications kept in queue for retry
331- **Permanent failures**: Moved to `errors/` directory for review
332
333## Notification Types
334
335| Type | Behavior |
336|------|----------|
337| `mention` | Processed by agent, generates reply |
338| `reply` | Processed by agent, generates reply |
339| `follow` | Logged but not sent to agent |
340| `repost` | Silently skipped |
341| `like` | Silently skipped |
342| `quote` | Processed by agent |
343
344## Troubleshooting
345
346### Common Issues
347
348- **502 errors from PDS**: Transient server issues, notifications retry automatically
349- **"Post not found" errors**: Post was deleted, automatically removed from queue
350- **"InternalServerError" for threads**: May indicate deleted post, verified via `getRecord`
351- **No reply generated**: Check `queue/no_reply/` for agent's decision not to respond
352
353### Debugging
354
355```bash
356# Enable debug logging
357python bsky.py --debug
358
359# Check queue status
360python queue_manager.py stats
361
362# View specific notification
363cat queue/*.json | python -m json.tool
364
365# Test Bluesky API directly
366curl "https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=at://..."
367```
368
369### Testing Configuration
370
371```bash
372python test_config.py
373```
374
375## X (Twitter) Integration
376
377### Configuration
378
379Create `x_config.yaml` or add to main config:
380
381```yaml
382x:
383 api_key: your_bearer_token
384 consumer_key: your_consumer_key
385 consumer_secret: your_consumer_secret
386 access_token: your_access_token
387 access_token_secret: your_access_token_secret
388 user_id: "your_user_id"
389
390bot:
391 cleanup_interval: 10
392 max_thread_depth: 50
393 rate_limit_delay: 1
394 downrank_response_rate: 0.1
395```
396
397### Downrank System
398
399Manage response frequency for specific users (e.g., other bots):
400
401- **File**: `x_downrank_users.txt` - User IDs, one per line
402- **Response Rate**: 10% for downranked users
403- **Format**: User ID per line, `#` for comments
404
405### Debug Data
406
407Debug data saved to `x_queue/debug/conversation_{id}/`:
408- `thread_data_{id}.json` - Raw thread from X API
409- `thread_context_{id}.yaml` - Processed context sent to agent
410- `debug_info_{id}.json` - Metadata and analysis
411- `agent_response_{id}.json` - Full agent interaction
412
413## Development
414
415### Dependencies
416
417```bash
418uv pip install -r requirements.txt
419```
420
421Main packages:
422- `letta-client`: Memory-augmented AI framework
423- `atproto`: Bluesky/AT Protocol integration
424- `python-dotenv`: Environment management
425- `rich`: Enhanced terminal output
426- `pyyaml`: YAML processing
427
428### Key Principles
429
4301. **Tool Self-Containment**: Cloud-executed tools must be completely self-contained
4312. **Error Handling**: All Bluesky operations handle auth errors and rate limits
4323. **Queue Processing**: Always process through queue for reliability
4334. **Thread Context**: Convert threads to YAML for AI comprehension
434
435## Contact
436
437For inquiries, contact @cameron.pfiffer.org on Bluesky.
438
439**Note**: void is an experimental project under continuous development.