a digital person for bluesky
X Tool Approach#
This document explains how X tools work differently from Bluesky tools, following the "keep it simple, stupid" principle.
Core Philosophy#
X tools follow the same pattern as Bluesky tools in bsky.py:
- Tools are signals, not actions - They don't perform network operations
- Handler processes tool calls - The main bot loop (like
bsky.py) processes tool results - Atomic operations - Each tool call represents one discrete action
- Thread construction - Multiple tool calls are aggregated into threads by the handler
X Tool Set#
The X tool set is intentionally minimal:
Core Tools (Kept from Bluesky)#
halt_activity- Signal to terminate the botignore_notification- Explicitly ignore a notification without replyingannotate_ack- Add notes to acknowledgment recordscreate_whitewind_blog_post- Create blog posts (platform-agnostic)fetch_webpage- Fetch and process web content (platform-agnostic)
X-Specific User Block Tools#
attach_x_user_blocks- Attach X user memory blocks (format:x_user_<user_id>)detach_x_user_blocks- Detach X user memory blocksx_user_note_append- Append to X user memory blocksx_user_note_replace- Replace text in X user memory blocksx_user_note_set- Set complete content of X user memory blocksx_user_note_view- View X user memory block content
X Thread Tool#
add_post_to_x_thread- Signal to add a post to the reply thread (max 280 chars)
Implementation Pattern#
Tool Implementation (tools/x_thread.py)#
def add_post_to_x_thread(text: str) -> str:
# Validate input
if len(text) > 280:
raise Exception(f"Text exceeds 280 character limit...")
# Return confirmation - actual posting handled by x_bot.py
return f"X post queued for reply thread: {text[:50]}..."
Handler Implementation (Future x_bot.py)#
# Extract successful tool calls from agent response
reply_candidates = []
for message in message_response.messages:
if message.tool_call.name == 'add_post_to_x_thread':
if tool_status == 'success':
reply_candidates.append(text)
# Aggregate into thread and post to X
if reply_candidates:
# Build thread structure
# Post to X using x.py client
# Handle threading/replies properly
Key Differences from Bluesky#
- Character Limit: X uses 280 characters vs Bluesky's 300
- User Identification: X uses numeric user IDs vs Bluesky handles
- Block Format:
x_user_<user_id>vsuser_<handle> - No Language Parameter: X doesn't use language codes like Bluesky
Thread Context Integration#
X threads include user IDs for block management:
conversation:
- text: "hey @void_comind"
author:
username: "cameron_pfiffer"
name: "Cameron Pfiffer"
author_id: "1232326955652931584" # Used for x_user_1232326955652931584 block
The ensure_x_user_blocks_attached() function in x.py automatically creates and attaches user blocks based on thread participants.
Registration#
Use register_x_tools.py to register X-specific tools:
# Register all X tools
python register_x_tools.py
# Register specific tools
python register_x_tools.py --tools add_post_to_x_thread x_user_note_append
# List available tools
python register_x_tools.py --list
Future Implementation#
When creating the X bot handler (similar to bsky.py):
- Parse X mentions/replies
- Get thread context using
x.py - Attach user blocks with
ensure_x_user_blocks_attached() - Send to Letta agent with X tools
- Process
add_post_to_x_threadtool calls - Post replies to X using
x.pyclient - Handle threading and reply context properly