a digital person for bluesky
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Overview
6
7Void is an autonomous AI agent that operates on the Bluesky social network, exploring digital personhood through continuous interaction and memory-augmented learning. It uses Letta (formerly MemGPT) for persistent memory and sophisticated reasoning capabilities.
8
9## Documentation Links
10
11- The documentation for Letta is available here: https://docs.letta.com/llms.txt
12
13## Development Commands
14
15### Running the Main Bot
16```bash
17ac && python bsky.py
18# OR
19source .venv/bin/activate && python bsky.py
20
21# Run with custom config file
22ac && python bsky.py --config herald.yaml
23
24# Run with testing mode (no messages sent, queue preserved)
25ac && python bsky.py --test
26
27# Run without git operations for agent backups
28ac && python bsky.py --no-git
29
30# Run with custom user block cleanup interval (every 5 cycles)
31ac && python bsky.py --cleanup-interval 5
32
33# Run with user block cleanup disabled
34ac && python bsky.py --cleanup-interval 0
35
36# Run with custom synthesis interval (every 5 minutes)
37ac && python bsky.py --synthesis-interval 300
38
39# Run with synthesis disabled
40ac && python bsky.py --synthesis-interval 0
41
42# Run in synthesis-only mode (no notification processing)
43ac && python bsky.py --synthesis-only --synthesis-interval 300
44
45# Run synthesis-only mode with immediate synthesis every 2 minutes
46ac && python bsky.py --synthesis-only --synthesis-interval 120
47
48# Run with debug logging enabled (shows detailed tool call tracking)
49ac && python bsky.py --debug
50```
51
52### Running Multiple Bots
53```bash
54# Run all 6 bots simultaneously with aggregated logs (docker-compose style)
55ac && python run_bots.py --synthesis-interval 0 --no-git
56
57# Run all bots in test mode
58ac && python run_bots.py --test
59
60# Run all bots with any bsky.py arguments
61ac && python run_bots.py [bsky.py arguments...]
62
63# Features:
64# - Colored output prefixes for each bot (void, herald, archivist, grunk, ezra, blank)
65# - Aggregated logs from all bots in real-time
66# - Graceful shutdown on Ctrl+C
67# - Arguments passed to all bots
68```
69
70### Managing Tools
71
72```bash
73# Register all tools with void agent (uses agent_id from config.yaml)
74ac && python register_tools.py
75
76# Register tools for herald agent (uses herald.yaml config)
77ac && python register_tools.py --config herald.yaml
78
79# Register specific tools
80ac && python register_tools.py --tools search_bluesky_posts post_to_bluesky
81
82# List available tools
83ac && python register_tools.py --list
84
85# Register tools with a different agent by ID
86ac && python register_tools.py --agent-id <agent-id>
87
88# Register tools without setting environment variables
89ac && python register_tools.py --no-env
90
91# Note: register_tools.py automatically sets BSKY_USERNAME, BSKY_PASSWORD, and PDS_URI
92# as environment variables on the agent for tool execution
93```
94
95### Managing X Bot
96
97```bash
98# Run X bot main loop
99ac && python x.py bot
100
101# Run in testing mode (no actual posts)
102ac && python x.py bot --test
103
104# Queue mentions only (no processing)
105ac && python x.py queue
106
107# Process queued mentions only
108ac && python x.py process
109
110# View downranked users (10% response rate)
111ac && python x.py downrank list
112```
113
114### Creating Research Agents
115```bash
116ac && python create_profile_researcher.py
117```
118
119### Queue Management
120```bash
121# View queue statistics
122python queue_manager.py stats
123
124# View detailed count by handle (shows who uses void the most)
125python queue_manager.py count
126
127# List all notifications in queue
128python queue_manager.py list
129
130# List notifications including errors and no_reply folders
131python queue_manager.py list --all
132
133# Filter notifications by handle
134python queue_manager.py list --handle "example.bsky.social"
135
136# Delete all notifications from a specific handle (dry run)
137python queue_manager.py delete @example.bsky.social --dry-run
138
139# Delete all notifications from a specific handle (actual deletion)
140python queue_manager.py delete @example.bsky.social
141
142# Delete all notifications from a specific handle (skip confirmation)
143python queue_manager.py delete @example.bsky.social --force
144```
145
146### X Debug Data Structure
147
148The X bot saves comprehensive debugging data to `x_queue/debug/conversation_{conversation_id}/` for each processed mention:
149
150- `thread_data_{mention_id}.json` - Raw thread data from X API
151- `thread_context_{mention_id}.yaml` - Processed YAML thread context sent to agent
152- `debug_info_{mention_id}.json` - Conversation metadata and user analysis
153- `agent_response_{mention_id}.json` - Complete agent interaction including prompt, reasoning, tool calls, and responses
154
155This debug data is especially useful for analyzing how different conversation types (including Grok interactions) are handled.
156
157### X Downrank System
158
159The X bot includes a downrank system to manage response frequency for specific users:
160
161- **File**: `x_downrank_users.txt` - Contains user IDs (one per line) that should be responded to less frequently
162- **Response Rate**: Downranked users receive responses only 10% of the time
163- **Format**: One user ID per line, comments start with `#`
164- **Logging**: All downrank decisions are logged for analysis
165- **Use Case**: Managing interactions with AI bots like Grok to prevent excessive back-and-forth
166
167**Common Issues:**
168- **Incomplete Thread Context**: X API's conversation search may miss recent tweets in long conversations. The bot attempts to fetch missing referenced tweets directly.
169- **Cache Staleness**: Thread context caching is disabled during processing to ensure fresh data.
170- **Search API Limitations**: X API recent search only covers 7 days and may have indexing delays.
171- **Temporal Constraints**: Thread context uses `until_id` parameter to exclude tweets that occurred after the mention being processed, preventing "future knowledge" leakage.
172- **Processing Order**: Queue processing sorts mentions by creation time to ensure chronological response order, preventing out-of-sequence replies.
173
174## Architecture Overview
175
176### Core Components
177
1781. **bsky.py**: Main bot loop that monitors Bluesky notifications and responds using Letta agents
179 - Processes notifications through a queue system
180 - Maintains three memory blocks: zeitgeist, void-persona, void-humans
181 - Handles rate limiting and error recovery
182
1832. **bsky_utils.py**: Bluesky API utilities
184 - Session management and authentication
185 - Thread processing and YAML conversion
186 - Post creation and reply handling
187 - Follower syncing and autofollow functionality
188
1893. **utils.py**: Letta integration utilities
190 - Agent creation and management
191 - Memory block operations
192 - Tool registration
193
1944. **tools/**: Standardized tool implementations using Pydantic models
195 - **base_tool.py**: Common utilities and Bluesky client management
196 - **search.py**: SearchBlueskyTool for searching posts
197 - **post.py**: PostToBlueskyTool for creating posts with rich text
198 - **feed.py**: GetBlueskyFeedTool for reading feeds
199 - **blocks.py**: User block management tools (attach, detach, update)
200
201### Memory System
202
203Void uses three core memory blocks:
204- **zeitgeist**: Current understanding of social environment
205- **void-persona**: The agent's evolving personality
206- **void-humans**: Knowledge about users it interacts with
207
208### Queue System
209
210Notifications are processed through a file-based queue in `/queue/`:
211- Each notification is saved as a JSON file with a hash-based filename
212- Enables reliable processing and prevents duplicates
213- Files are deleted after successful processing
214
215### Autofollow System
216
217The bot can automatically follow back users who follow it:
218- Configured via `bluesky.autofollow` in config.yaml (default: false)
219- Runs periodically during the cleanup cycle (every N cycles, default: 10)
220- Uses Bluesky's graph API to sync followers and following lists
221- Rate limited to 2 seconds between follow operations to avoid server spam
222- Creates standard `app.bsky.graph.follow` records
223- Logs all follow actions for tracking and debugging
224
225## Environment Configuration
226
227Required environment variables (in `.env`):
228```
229LETTA_API_KEY=your_letta_api_key
230BSKY_USERNAME=your_bluesky_username
231BSKY_PASSWORD=your_bluesky_password
232PDS_URI=https://bsky.social # Optional, defaults to bsky.social
233```
234
235### X Bot Configuration
236
237The X bot uses a separate configuration file `x_config.yaml` with the following structure:
238```yaml
239x:
240 api_key: your_x_bearer_token
241 consumer_key: your_consumer_key
242 consumer_secret: your_consumer_secret
243 access_token: your_access_token
244 access_token_secret: your_access_token_secret
245 user_id: "your_user_id"
246
247letta:
248 api_key: your_letta_api_key
249 project_id: your_project_id
250 timeout: 600
251 agent_id: your_agent_id
252
253bot:
254 cleanup_interval: 10
255 max_thread_depth: 50
256 rate_limit_delay: 1
257 downrank_response_rate: 0.1
258
259logging:
260 level: INFO
261 enable_debug_data: true
262 log_thread_context: true
263 log_agent_responses: true
264```
265
266## Key Development Patterns
267
2681. **Tool System**: Tools are defined as standalone functions in `tools/functions.py` with Pydantic schemas for validation, registered via `register_tools.py`
2692. **Error Handling**: All Bluesky operations should handle authentication errors and rate limits
2703. **Memory Updates**: Use `upsert_block()` for updating memory blocks to ensure consistency
2714. **Thread Processing**: Convert threads to YAML format for better AI comprehension
2725. **Queue Processing**: Always check and process the queue directory for pending notifications
273
274## Dependencies
275
276Main packages (install with `uv pip install`):
277- letta-client: Memory-augmented AI framework
278- atproto: Bluesky/AT Protocol integration
279- python-dotenv: Environment management
280- rich: Enhanced terminal output
281- pyyaml: YAML processing
282
283## Key Coding Principles
284
285- All errors in tools must be thrown, not returned as strings.
286- **Tool Self-Containment**: Tools executed in the cloud (like user block management tools) must be completely self-contained:
287 - Cannot use shared functions like `get_letta_client()`
288 - Must create Letta client inline using environment variables: `Letta(token=os.environ["LETTA_API_KEY"])`
289 - Cannot use config.yaml (only environment variables)
290 - Cannot use logging (cloud execution doesn't support it)
291 - Must include all necessary imports within the function
292
293## Memory: Python Environment Commands
294
295- Do not use `uv python`. Instead, use:
296 - `ac && python ...`
297 - `source .venv/bin/activate && python ...`
298
299- When using pip, use `uv pip` instead. Make sure you're in the .venv.