a digital person for bluesky

Add bluesky_reply tool for Letta agent responses

- Created new reply.py tool module with bluesky_reply function
- Added 300 character validation to match Bluesky's limit
- Registered the tool in register_tools.py
- This simple tool allows the Letta agent to indicate when it wants to send a reply

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+41
tools
+7
register_tools.py
··· 14 from tools.post import create_new_bluesky_post, PostArgs 15 from tools.feed import get_bluesky_feed, FeedArgs 16 from tools.blocks import attach_user_blocks, detach_user_blocks, AttachUserBlocksArgs, DetachUserBlocksArgs 17 18 load_dotenv() 19 logging.basicConfig(level=logging.INFO) ··· 52 "args_schema": DetachUserBlocksArgs, 53 "description": "Detach user-specific memory blocks from the agent. Blocks are preserved for later use.", 54 "tags": ["memory", "blocks", "user"] 55 }, 56 ] 57
··· 14 from tools.post import create_new_bluesky_post, PostArgs 15 from tools.feed import get_bluesky_feed, FeedArgs 16 from tools.blocks import attach_user_blocks, detach_user_blocks, AttachUserBlocksArgs, DetachUserBlocksArgs 17 + from tools.reply import bluesky_reply, ReplyArgs 18 19 load_dotenv() 20 logging.basicConfig(level=logging.INFO) ··· 53 "args_schema": DetachUserBlocksArgs, 54 "description": "Detach user-specific memory blocks from the agent. Blocks are preserved for later use.", 55 "tags": ["memory", "blocks", "user"] 56 + }, 57 + { 58 + "func": bluesky_reply, 59 + "args_schema": ReplyArgs, 60 + "description": "Simple reply indicator for the Letta agent (max 300 chars)", 61 + "tags": ["bluesky", "reply", "response"] 62 }, 63 ] 64
+34
tools/reply.py
···
··· 1 + """Reply tool for Bluesky - a simple tool for the Letta agent to indicate a reply.""" 2 + from pydantic import BaseModel, Field, validator 3 + 4 + 5 + class ReplyArgs(BaseModel): 6 + message: str = Field( 7 + ..., 8 + description="The reply message text (max 300 characters)" 9 + ) 10 + 11 + @validator('message') 12 + def validate_message_length(cls, v): 13 + if len(v) > 300: 14 + raise ValueError(f"Message cannot be longer than 300 characters (current: {len(v)} characters)") 15 + return v 16 + 17 + 18 + def bluesky_reply(message: str) -> str: 19 + """ 20 + This is a simple function that returns a string. MUST be less than 300 characters. 21 + 22 + Args: 23 + message: The reply text (max 300 characters) 24 + 25 + Returns: 26 + Confirmation message 27 + 28 + Raises: 29 + Exception: If message exceeds 300 characters 30 + """ 31 + if len(message) > 300: 32 + raise Exception(f"Message cannot be longer than 300 characters (current: {len(message)} characters)") 33 + 34 + return 'Reply sent'