a digital person for bluesky
1# X Tool Approach
2
3This document explains how X tools work differently from Bluesky tools, following the "keep it simple, stupid" principle.
4
5## Core Philosophy
6
7X tools follow the same pattern as Bluesky tools in `bsky.py`:
8
91. **Tools are signals, not actions** - They don't perform network operations
102. **Handler processes tool calls** - The main bot loop (like `bsky.py`) processes tool results
113. **Atomic operations** - Each tool call represents one discrete action
124. **Thread construction** - Multiple tool calls are aggregated into threads by the handler
13
14## X Tool Set
15
16The X tool set is intentionally minimal:
17
18### Core Tools (Kept from Bluesky)
19- `halt_activity` - Signal to terminate the bot
20- `ignore_notification` - Explicitly ignore a notification without replying
21- `annotate_ack` - Add notes to acknowledgment records
22- `create_whitewind_blog_post` - Create blog posts (platform-agnostic)
23- `fetch_webpage` - Fetch and process web content (platform-agnostic)
24
25### X-Specific User Block Tools
26- `attach_x_user_blocks` - Attach X user memory blocks (format: `x_user_<user_id>`)
27- `detach_x_user_blocks` - Detach X user memory blocks
28- `x_user_note_append` - Append to X user memory blocks
29- `x_user_note_replace` - Replace text in X user memory blocks
30- `x_user_note_set` - Set complete content of X user memory blocks
31- `x_user_note_view` - View X user memory block content
32
33### X Thread Tool
34- `add_post_to_x_thread` - Signal to add a post to the reply thread (max 280 chars)
35
36## Implementation Pattern
37
38### Tool Implementation (`tools/x_thread.py`)
39```python
40def add_post_to_x_thread(text: str) -> str:
41 # Validate input
42 if len(text) > 280:
43 raise Exception(f"Text exceeds 280 character limit...")
44
45 # Return confirmation - actual posting handled by x_bot.py
46 return f"X post queued for reply thread: {text[:50]}..."
47```
48
49### Handler Implementation (Future `x_bot.py`)
50```python
51# Extract successful tool calls from agent response
52reply_candidates = []
53for message in message_response.messages:
54 if message.tool_call.name == 'add_post_to_x_thread':
55 if tool_status == 'success':
56 reply_candidates.append(text)
57
58# Aggregate into thread and post to X
59if reply_candidates:
60 # Build thread structure
61 # Post to X using x.py client
62 # Handle threading/replies properly
63```
64
65## Key Differences from Bluesky
66
671. **Character Limit**: X uses 280 characters vs Bluesky's 300
682. **User Identification**: X uses numeric user IDs vs Bluesky handles
693. **Block Format**: `x_user_<user_id>` vs `user_<handle>`
704. **No Language Parameter**: X doesn't use language codes like Bluesky
71
72## Thread Context Integration
73
74X threads include user IDs for block management:
75
76```yaml
77conversation:
78 - text: "hey @void_comind"
79 author:
80 username: "cameron_pfiffer"
81 name: "Cameron Pfiffer"
82 author_id: "1232326955652931584" # Used for x_user_1232326955652931584 block
83```
84
85The `ensure_x_user_blocks_attached()` function in `x.py` automatically creates and attaches user blocks based on thread participants.
86
87## Registration
88
89Use `register_x_tools.py` to register X-specific tools:
90
91```bash
92# Register all X tools
93python register_x_tools.py
94
95# Register specific tools
96python register_x_tools.py --tools add_post_to_x_thread x_user_note_append
97
98# List available tools
99python register_x_tools.py --list
100```
101
102## Future Implementation
103
104When creating the X bot handler (similar to `bsky.py`):
105
1061. Parse X mentions/replies
1072. Get thread context using `x.py`
1083. Attach user blocks with `ensure_x_user_blocks_attached()`
1094. Send to Letta agent with X tools
1105. Process `add_post_to_x_thread` tool calls
1116. Post replies to X using `x.py` client
1127. Handle threading and reply context properly