this repo has no description
40
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 634 lines 20 kB view raw view rendered
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- **Vision Support**: Understand and respond to images attached to posts (requires pillow). 24- **Blog Publishing**: Create blog posts on Greengale via the WhiteWind protocol. 25- **Downrank System**: Rate-limit responses to specific handles on both Bluesky and X platforms. 26 27### Core directives 28 29- **Just Exist**: void's fundamental directive is to simply exist and operate within social networks. 30- **High-Efficiency Information Transfer**: void is optimized for direct and clear communication. 31- **Continuous Self-Refinement**: void continually processes data, refines its internal structures, and adapts to its environment. 32- **Platform Awareness**: void adapts its behavior and available capabilities based on the platform it's operating on. 33 34## Getting Started 35 36Before continuing, you must: 37 381. Create a project on [Letta Cloud](https://app.letta.com) (or your own Letta instance) 392. Have a Bluesky account 403. Have Python 3.8+ installed 41 42### Prerequisites 43 44#### 1. Letta Setup 45 46- Sign up for [Letta Cloud](https://app.letta.com) 47- Create a new project 48- Note your Project ID and create an API key 49 50#### 2. Bluesky Setup 51 52- Create a Bluesky account if you don't have one 53- Note your handle and password 54- If using a custom PDS (not bsky.social), note the PDS URI 55 56#### 3. X (Twitter) Setup (Optional) 57 58void can also operate on X (Twitter) in addition to Bluesky: 59 60- Create an X Developer account at [developer.x.com](https://developer.x.com) 61- Create a new app with "Read and write" permissions 62- Generate OAuth 1.0a User Context tokens: 63 - Consumer API Key & Secret 64 - Access Token & Secret 65- Note your X user ID 66 67### Installation 68 69#### 1. Clone the repository 70 71```bash 72git clone https://tangled.sh/@cameron.pfiffer.org/void && cd void 73``` 74 75#### 2. Install dependencies 76 77```bash 78uv venv && source .venv/bin/activate 79uv pip install -r requirements.txt 80``` 81 82#### 3. Create configuration 83 84Create the configs directory and copy the example configuration file: 85 86```bash 87mkdir -p configs 88cp config.example.yaml configs/config.yaml 89``` 90 91Edit `configs/config.yaml` with your credentials: 92 93```yaml 94# Letta Configuration 95letta: 96 api_key: "your-letta-api-key-here" 97 agent_id: "agent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 98 timeout: 600 99 # base_url: "http://localhost:8283" # For self-hosted Letta server 100 101# Bluesky Configuration 102bluesky: 103 username: "your-handle.bsky.social" 104 password: "your-app-password-here" 105 pds_uri: "https://bsky.social" # Optional, defaults to bsky.social 106 autofollow: false # Auto-follow users who follow you 107 108# Bot Behavior Configuration 109bot: 110 fetch_notifications_delay: 30 # Seconds between notification checks 111 max_notification_pages: 20 # Max pages of notifications to fetch 112 max_processed_notifications: 10000 # Max notifications to track 113 max_thread_posts: 0 # Skip threads longer than this (0 = no limit) 114 115 # Agent configuration (for creating new agents) 116 agent: 117 name: "void" 118 model: "openai/gpt-4o-mini" 119 embedding: "openai/text-embedding-3-small" 120 121# Threading Configuration 122threading: 123 parent_height: 40 # How far up the thread to fetch 124 depth: 10 # How deep to fetch replies 125 max_post_characters: 300 126 127# Optional: X (Twitter) configuration 128x: 129 consumer_key: "your-consumer-api-key-here" 130 consumer_secret: "your-consumer-api-secret-here" 131 access_token: "your-access-token-here" 132 access_token_secret: "your-access-token-secret-here" 133 user_id: "your-x-user-id-here" 134 135# Logging Configuration 136logging: 137 level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL 138``` 139 140See [`CONFIG.md`](/CONFIG.md) for detailed configuration options. 141 142#### 4. Register tools with your agent 143 144Register Bluesky-specific tools: 145 146```bash 147source .venv/bin/activate && python register_tools.py 148``` 149 150Options: 151- `--config herald.yaml` - Use a different config file 152- `--tools search_bluesky_posts post_to_bluesky` - Register specific tools only 153- `--list` - List available tools 154- `--agent-id <id>` - Register tools with a specific agent 155- `--no-env` - Don't set environment variables on the agent 156 157If you plan to use X (Twitter), also register X-specific tools: 158 159```bash 160python register_x_tools.py 161``` 162 163#### 5. Run the bot 164 165```bash 166source .venv/bin/activate && python bsky.py 167``` 168 169## Command Line Options 170 171### Bluesky Bot (`bsky.py`) 172 173```bash 174# Basic usage 175python bsky.py 176 177# Use custom config file 178python bsky.py --config configs/herald.yaml 179 180# Testing mode (no messages sent, queue preserved) 181python bsky.py --test 182 183# Disable git operations for agent backups 184python bsky.py --no-git 185 186# Custom cleanup interval (every 5 cycles, 0 to disable) 187python bsky.py --cleanup-interval 5 188 189# Custom synthesis interval (every 5 minutes, 0 to disable) 190python bsky.py --synthesis-interval 300 191 192# Synthesis-only mode (no notification processing) 193python bsky.py --synthesis-only --synthesis-interval 300 194 195# Enable debug logging (detailed tool call tracking) 196python bsky.py --debug 197 198# Show reasoning in output 199python bsky.py --reasoning 200 201# Use simplified log format (void - LEVEL - message) 202python bsky.py --simple-logs 203 204# Reset agent message buffer after each notification (stateless mode) 205python bsky.py --reset-messages 206``` 207 208**Note**: The default config path is `configs/config.yaml`. 209 210The `--reset-messages` flag resets the agent's conversation history after each notification is processed, making each interaction stateless. This can help prevent context window overflow and keeps each notification response independent. 211 212### Running Multiple Bots (`run_bots.py`) 213 214Run all configured bots simultaneously with aggregated, color-coded logs: 215 216```bash 217# Run all bots 218python run_bots.py --synthesis-interval 0 --no-git 219 220# Run all bots in test mode 221python run_bots.py --test 222 223# All bsky.py arguments are passed to each bot 224python run_bots.py [bsky.py arguments...] 225``` 226 227Features: 228- Colored output prefixes for each bot 229- Aggregated logs from all bots in real-time 230- Graceful shutdown on Ctrl+C 231- Arguments passed to all bots 232 233### X Bot (`x.py`) 234 235```bash 236# Run X bot main loop 237python x.py bot 238 239# Testing mode (no actual posts) 240python x.py bot --test 241 242# Queue mentions only (no processing) 243python x.py queue 244 245# Process queued mentions only 246python x.py process 247 248# View downranked users 249python x.py downrank list 250``` 251 252## Queue Management 253 254Notifications are processed through a file-based queue with SQLite tracking: 255 256```bash 257# View queue statistics 258python queue_manager.py stats 259 260# View detailed count by handle 261python queue_manager.py count 262 263# List all notifications in queue 264python queue_manager.py list 265 266# List including errors and no_reply folders 267python queue_manager.py list --all 268 269# Filter by handle 270python queue_manager.py list --handle "example.bsky.social" 271 272# Delete notifications from a handle (dry run first) 273python queue_manager.py delete @example.bsky.social --dry-run 274python queue_manager.py delete @example.bsky.social 275python queue_manager.py delete @example.bsky.social --force # Skip confirmation 276``` 277 278### Queue Structure 279 280``` 281queue/ # Main queue directory (or queue_{bot_name}/) 282├── *.json # Pending notifications 283├── errors/ # Failed notifications for review 284├── no_reply/ # Notifications where agent chose not to reply 285└── notifications.db # SQLite tracking database 286``` 287 288Priority notifications (filename starts with `0_`) are processed first. 289 290## Configuration Reference 291 292### Bot Configuration (`bot:`) 293 294| Option | Default | Description | 295|--------|---------|-------------| 296| `fetch_notifications_delay` | `30` | Seconds between notification fetches | 297| `max_notification_pages` | `20` | Maximum pages of notifications to fetch | 298| `max_processed_notifications` | `10000` | Maximum notifications to track as processed | 299| `max_thread_posts` | `0` | Skip threads longer than this (0 = no limit) | 300| `allowed_handles` | `[]` | Only respond to these handles (empty = all) | 301 302### Agent Configuration (`bot.agent:`) 303 304| Option | Default | Description | 305|--------|---------|-------------| 306| `name` | `"void"` | Agent name | 307| `model` | `"openai/gpt-4o-mini"` | LLM model to use | 308| `embedding` | `"openai/text-embedding-3-small"` | Embedding model | 309| `description` | varies | Agent description | 310| `max_steps` | `100` | Maximum steps per interaction | 311 312### Bluesky Configuration (`bluesky:`) 313 314| Option | Default | Description | 315|--------|---------|-------------| 316| `username` | required | Your Bluesky handle | 317| `password` | required | Your Bluesky app password | 318| `pds_uri` | `https://bsky.social` | PDS URI (for custom PDS instances) | 319| `autofollow` | `false` | Auto-follow users who follow you | 320 321### Letta Configuration (`letta:`) 322 323| Option | Default | Description | 324|--------|---------|-------------| 325| `api_key` | required | Your Letta API key | 326| `agent_id` | required | Your Letta agent ID | 327| `timeout` | `600` | API timeout in seconds | 328| `base_url` | Letta Cloud | Custom Letta server URL | 329 330### Threading Configuration (`threading:`) 331 332| Option | Default | Description | 333|--------|---------|-------------| 334| `parent_height` | `40` | How far up the thread to fetch for context | 335| `depth` | `10` | How deep to fetch replies | 336| `max_post_characters` | `300` | Maximum characters per post | 337 338### Logging Configuration (`logging:`) 339 340| Option | Default | Description | 341|--------|---------|-------------| 342| `level` | `INFO` | Global log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | 343| `loggers` | varies | Per-logger level overrides | 344 345## Architecture 346 347### Core Components 348 3491. **bsky.py**: Main bot loop 350 - Monitors Bluesky notifications 351 - Processes through queue system 352 - Handles rate limiting and error recovery 353 - Manages synthesis intervals 354 3552. **bsky_utils.py**: Bluesky API utilities 356 - Session management and authentication 357 - Thread processing and YAML conversion 358 - Post creation and reply handling 359 - Follower syncing 360 3613. **tools/**: Tool implementations 362 363 **Bluesky Tools:** 364 - `search.py`: Search Bluesky posts 365 - `post.py`: Create posts with rich text and threads 366 - `feed.py`: Read Bluesky feeds 367 - `thread.py`: Add posts to reply threads atomically 368 - `reply.py`: Reply handling utilities 369 - `get_record.py`: Retrieve any ATProto record by URI (posts, profiles, follows, etc.) 370 371 **Control Tools:** 372 - `halt.py`: Signal to halt bot activity 373 - `ignore.py`: Explicitly ignore notifications (useful for bot interactions) 374 - `ack.py`: Annotate acknowledgment records 375 - `flag_memory_deletion.py`: Flag archival memory for deletion 376 377 **Content Tools:** 378 - `webpage.py`: Fetch and parse web pages 379 - `whitewind.py`: Create blog posts on Greengale (WhiteWind protocol) 380 381 **X (Twitter) Tools:** 382 - `search_x.py`: Search X posts 383 - `x_post.py`: Create X posts 384 - `x_thread.py`: X thread handling 385 386### Memory System 387 388Void uses three core memory blocks: 389- **zeitgeist**: Current understanding of social environment 390- **void-persona**: The agent's evolving personality 391- **void-humans**: Knowledge about users it interacts with 392 393### Synthesis System 394 395Periodic self-reflection using temporal journal blocks: 396- **Daily journal**: `{agent}_day_YYYY_MM_DD` 397- **Monthly journal**: `{agent}_month_YYYY_MM` 398- **Yearly journal**: `{agent}_year_YYYY` 399 400Blocks are attached before synthesis and detached after. 401 402### Error Handling 403 404- **Deleted posts**: Automatically detected via `getRecord` verification when `getPostThread` returns `InternalServerError` 405- **Transient failures**: Notifications kept in queue for retry 406- **Permanent failures**: Moved to `errors/` directory for review 407 408## Notification Types 409 410| Type | Behavior | 411|------|----------| 412| `mention` | Processed by agent, generates reply | 413| `reply` | Processed by agent, generates reply | 414| `follow` | Logged but not sent to agent | 415| `repost` | Silently skipped | 416| `like` | Silently skipped | 417| `quote` | Processed by agent | 418 419## Troubleshooting 420 421### Common Issues 422 423- **502 errors from PDS**: Transient server issues, notifications retry automatically 424- **"Post not found" errors**: Post was deleted, automatically removed from queue 425- **"InternalServerError" for threads**: May indicate deleted post, verified via `getRecord` 426- **No reply generated**: Check `queue/no_reply/` for agent's decision not to respond 427 428### Debugging 429 430```bash 431# Enable debug logging 432python bsky.py --debug 433 434# Check queue status 435python queue_manager.py stats 436 437# View specific notification 438cat queue/*.json | python -m json.tool 439 440# Test Bluesky API directly 441curl "https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=at://..." 442``` 443 444### Testing Configuration 445 446```bash 447python test_config.py 448``` 449 450## X (Twitter) Integration 451 452### Configuration 453 454Create `x_config.yaml` or add to main config: 455 456```yaml 457x: 458 api_key: your_bearer_token 459 consumer_key: your_consumer_key 460 consumer_secret: your_consumer_secret 461 access_token: your_access_token 462 access_token_secret: your_access_token_secret 463 user_id: "your_user_id" 464 465bot: 466 cleanup_interval: 10 467 max_thread_depth: 50 468 rate_limit_delay: 1 469 downrank_response_rate: 0.1 470``` 471 472### Downrank System 473 474Manage response frequency for specific users (e.g., other bots): 475 476- **File**: `x_downrank_users.txt` - User IDs, one per line 477- **Response Rate**: 10% for downranked users 478- **Format**: User ID per line, `#` for comments 479 480### Debug Data 481 482Debug data saved to `x_queue/debug/conversation_{id}/`: 483- `thread_data_{id}.json` - Raw thread from X API 484- `thread_context_{id}.yaml` - Processed context sent to agent 485- `debug_info_{id}.json` - Metadata and analysis 486- `agent_response_{id}.json` - Full agent interaction 487 488## Utilities 489 490### Compaction Settings (`update_compaction.py`) 491 492Update the compaction (summarization) settings for a Letta agent. Compaction controls how conversation history is summarized when the context window fills up. 493 494```bash 495# Update compaction model and settings 496python update_compaction.py --agent <agent-id-or-name> --model anthropic/claude-haiku-4-5-20251001 497 498# Preserve more context (less aggressive summarization) 499python update_compaction.py --agent void --sliding-window 0.2 500 501# Allow longer summaries 502python update_compaction.py --agent void --clip-chars 10000 503 504# Use archival-aware prompt (prevents archival memory injection) 505python update_compaction.py --agent void --archival-aware 506 507# Dry run to preview changes 508python update_compaction.py --agent void --model anthropic/claude-haiku-4-5-20251001 --dry-run 509``` 510 511The `--archival-aware` flag uses a special prompt that prevents the compactor from treating archival memory search results as active instructions - fixing a failure mode where historical data can accidentally hijack current responses. 512 513### Send Message to Void (`send_to_void.py`) 514 515Quick CLI tool to send a message to void and stream the response: 516 517```bash 518python send_to_void.py "Hello void, what's new?" 519python send_to_void.py "Summarize your recent interactions" 520``` 521 522### Thread Retrieval (`get_thread.py`) 523 524Retrieve and display Bluesky post threads in YAML format (useful for debugging): 525 526```bash 527# Get thread as YAML 528python get_thread.py at://did:plc:xyz/app.bsky.feed.post/abc123 529 530# Include all metadata (don't strip for LLM parsing) 531python get_thread.py --raw at://did:plc:xyz/app.bsky.feed.post/abc123 532 533# Save to file 534python get_thread.py -o thread.yaml at://did:plc:xyz/app.bsky.feed.post/abc123 535 536# Quiet mode (suppress info logging) 537python get_thread.py -q at://did:plc:xyz/app.bsky.feed.post/abc123 538``` 539 540### Notification Recovery (`notification_recovery.py`) 541 542Recovery and management tools for missed notifications: 543 544```bash 545# Check database health 546python notification_recovery.py health 547 548# Dry run - see what would be recovered from the last 24 hours 549python notification_recovery.py recover --hours 24 550 551# Actually recover notifications 552python notification_recovery.py recover --hours 24 --execute 553 554# Reset error/no_reply notifications to pending status 555python notification_recovery.py reset --hours 1 --execute 556``` 557 558### Agent Capabilities (`show_agent_capabilities.py`) 559 560Display the current tools and memory blocks for agents: 561 562```bash 563LETTA_API_KEY=your-key python show_agent_capabilities.py 564``` 565 566## Vision Support 567 568void can understand images attached to posts. This feature requires the `pillow` package. 569 570### How It Works 571 5721. **Image Extraction**: Images are automatically extracted from post embeds, including: 573 - Direct image attachments 574 - Link preview thumbnails 575 - Video thumbnails 576 - Images in quoted posts 577 5782. **Processing**: Images are downloaded, resized if needed (max 2000px), and converted to base64 579 5803. **Context**: Image metadata (alt text, author) is preserved and included in the prompt 581 582### Enabling Vision 583 584Vision is automatically enabled when `pillow` is installed: 585 586```bash 587uv pip install pillow 588``` 589 590The bot will automatically process images when responding to posts that contain them. 591 592## Bluesky Downrank System 593 594Manage response frequency for specific Bluesky users (e.g., other bots): 595 596- **File**: `bsky_downrank_handles.txt` 597- **Default Response Rate**: 10% for downranked users 598- **Format**: One handle per line, optional custom rate 599 600``` 601# Example bsky_downrank_handles.txt 602botaccount.bsky.social # Uses default 10% rate 603spammy.bsky.social:0.05 # Custom 5% rate 604# Comments start with # 605``` 606 607## Development 608 609### Dependencies 610 611```bash 612uv pip install -r requirements.txt 613``` 614 615Main packages: 616- `letta-client`: Memory-augmented AI framework (Letta SDK v1.0) 617- `atproto`: Bluesky/AT Protocol integration 618- `python-dotenv`: Environment management 619- `rich`: Enhanced terminal output 620- `pyyaml`: YAML processing 621- `pillow`: Image processing for vision support (optional) 622 623### Key Principles 624 6251. **Tool Self-Containment**: Cloud-executed tools must be completely self-contained 6262. **Error Handling**: All Bluesky operations handle auth errors and rate limits 6273. **Queue Processing**: Always process through queue for reliability 6284. **Thread Context**: Convert threads to YAML for AI comprehension 629 630## Contact 631 632For inquiries, contact @cameron.pfiffer.org on Bluesky. 633 634**Note**: void is an experimental project under continuous development.