this repo has no description

Replace bluesky_reply with atomic add_post_to_bluesky_reply_thread tool

- Remove bluesky_reply tool to eliminate confusion with threading approach
- Add new add_post_to_bluesky_reply_thread tool for building reply threads atomically
- Each call adds a single post to the reply thread queue
- Handler (bsky.py) manages actual thread state and AT Protocol threading
- Better error recovery: individual post failures don't affect entire thread
- Added TOOL_CHANGELOG.md to document changes for agent migration

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

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

+124 -7
+67
TOOL_CHANGELOG.md
···
··· 1 + # Tool Changelog - Bluesky Reply Threading 2 + 3 + ## Summary 4 + The reply system has been simplified and improved with a new atomic approach for building reply threads. 5 + 6 + ## Changes Made 7 + 8 + ### ✅ NEW TOOL: `add_post_to_bluesky_reply_thread` 9 + - **Purpose**: Add a single post to the current Bluesky reply thread atomically 10 + - **Usage**: Call this tool multiple times to build a reply thread incrementally 11 + - **Parameters**: 12 + - `text` (required): Text content for the post (max 300 characters) 13 + - `lang` (optional): Language code (defaults to "en-US") 14 + - **Returns**: Confirmation that the post has been queued for the reply thread 15 + - **Error Handling**: If text exceeds 300 characters, the post will be omitted from the thread and you may try again with shorter text 16 + 17 + ### ❌ REMOVED TOOL: `bluesky_reply` 18 + - This tool has been removed to eliminate confusion 19 + - All reply functionality is now handled through the new atomic approach 20 + 21 + ## How to Use the New System 22 + 23 + ### Before (Old Way - NO LONGER AVAILABLE) 24 + ``` 25 + bluesky_reply(["First reply", "Second reply", "Third reply"]) 26 + ``` 27 + 28 + ### After (New Way - USE THIS) 29 + ``` 30 + add_post_to_bluesky_reply_thread("First reply") 31 + add_post_to_bluesky_reply_thread("Second reply") 32 + add_post_to_bluesky_reply_thread("Third reply") 33 + ``` 34 + 35 + ## Benefits of the New Approach 36 + 37 + 1. **Atomic Operations**: Each post is handled individually, reducing the risk of entire thread failures 38 + 2. **Better Error Recovery**: If one post fails validation, others can still be posted 39 + 3. **Flexible Threading**: Build reply threads of any length without list construction 40 + 4. **Clearer Intent**: Each tool call has a single, clear purpose 41 + 5. **Handler-Managed State**: The bsky.py handler manages thread state and proper AT Protocol threading 42 + 43 + ## Important Notes 44 + 45 + - The actual posting to Bluesky is handled by the bsky.py handler, not the tool itself 46 + - Each call to `add_post_to_bluesky_reply_thread` queues a post for the current reply context 47 + - Posts are validated for the 300-character limit before being queued 48 + - Thread state and proper reply chaining is managed automatically by the handler 49 + - Language defaults to "en-US" but can be specified per post if needed 50 + 51 + ## Migration Guide 52 + 53 + If you were previously using `bluesky_reply`, simply replace it with multiple calls to `add_post_to_bluesky_reply_thread`: 54 + 55 + **Old approach:** 56 + ``` 57 + bluesky_reply(["Hello!", "This is a threaded reply.", "Thanks for the mention!"]) 58 + ``` 59 + 60 + **New approach:** 61 + ``` 62 + add_post_to_bluesky_reply_thread("Hello!") 63 + add_post_to_bluesky_reply_thread("This is a threaded reply.") 64 + add_post_to_bluesky_reply_thread("Thanks for the mention!") 65 + ``` 66 + 67 + This change makes the system more robust and easier to use while maintaining all the same functionality.
+7 -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, user_note_append, user_note_replace, user_note_set, user_note_view, AttachUserBlocksArgs, DetachUserBlocksArgs, UserNoteAppendArgs, UserNoteReplaceArgs, UserNoteSetArgs, UserNoteViewArgs 17 - from tools.reply import bluesky_reply, ReplyArgs 18 from tools.halt import halt_activity, HaltArgs 19 20 load_dotenv() 21 logging.basicConfig(level=logging.INFO) ··· 80 "tags": ["memory", "blocks", "user", "view"] 81 }, 82 { 83 - "func": bluesky_reply, 84 - "args_schema": ReplyArgs, 85 - "description": "Reply indicator for the Letta agent (1-4 messages, each max 300 chars). Creates threaded replies.", 86 - "tags": ["bluesky", "reply", "response"] 87 - }, 88 - { 89 "func": halt_activity, 90 "args_schema": HaltArgs, 91 "description": "Signal to halt all bot activity and terminate bsky.py", 92 "tags": ["control", "halt", "terminate"] 93 }, 94 ] 95
··· 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, user_note_append, user_note_replace, user_note_set, user_note_view, AttachUserBlocksArgs, DetachUserBlocksArgs, UserNoteAppendArgs, UserNoteReplaceArgs, UserNoteSetArgs, UserNoteViewArgs 17 from tools.halt import halt_activity, HaltArgs 18 + from tools.thread import add_post_to_bluesky_reply_thread, ReplyThreadPostArgs 19 20 load_dotenv() 21 logging.basicConfig(level=logging.INFO) ··· 80 "tags": ["memory", "blocks", "user", "view"] 81 }, 82 { 83 "func": halt_activity, 84 "args_schema": HaltArgs, 85 "description": "Signal to halt all bot activity and terminate bsky.py", 86 "tags": ["control", "halt", "terminate"] 87 + }, 88 + { 89 + "func": add_post_to_bluesky_reply_thread, 90 + "args_schema": ReplyThreadPostArgs, 91 + "description": "Add a single post to the current Bluesky reply thread atomically", 92 + "tags": ["bluesky", "reply", "thread", "atomic"] 93 }, 94 ] 95
+50
tools/thread.py
···
··· 1 + """Thread tool for adding posts to Bluesky threads atomically.""" 2 + from typing import Optional 3 + from pydantic import BaseModel, Field, validator 4 + 5 + 6 + class ReplyThreadPostArgs(BaseModel): 7 + text: str = Field( 8 + ..., 9 + description="Text content for the post (max 300 characters)" 10 + ) 11 + lang: Optional[str] = Field( 12 + default="en-US", 13 + description="Language code for the post (e.g., 'en-US', 'es', 'ja', 'th'). Defaults to 'en-US'" 14 + ) 15 + 16 + @validator('text') 17 + def validate_text_length(cls, v): 18 + if len(v) > 300: 19 + raise ValueError(f"Text exceeds 300 character limit (current: {len(v)} characters)") 20 + return v 21 + 22 + 23 + def add_post_to_bluesky_reply_thread(text: str, lang: str = "en-US") -> str: 24 + """ 25 + Add a single post to the current Bluesky reply thread. This tool indicates to the handler 26 + that it should add this post to the ongoing reply thread context when responding to a notification. 27 + 28 + This is distinct from bluesky_reply which handles the complete reply process. Use this tool 29 + when you want to build a reply thread incrementally, adding posts one at a time. 30 + 31 + This is an atomic operation - each call adds exactly one post. The handler (bsky.py) 32 + manages the thread state and ensures proper threading when multiple posts are queued. 33 + 34 + Args: 35 + text: Text content for the post (max 300 characters) 36 + lang: Language code for the post (e.g., 'en-US', 'es', 'ja', 'th'). Defaults to 'en-US' 37 + 38 + Returns: 39 + Confirmation message that the post has been queued for the reply thread 40 + 41 + Raises: 42 + Exception: If text exceeds character limit. On failure, the post will be omitted 43 + from the reply thread and the agent may try again with corrected text. 44 + """ 45 + # Validate input 46 + if len(text) > 300: 47 + raise Exception(f"Text exceeds 300 character limit (current: {len(text)} characters). This post will be omitted from the thread. You may try again with shorter text.") 48 + 49 + # Return confirmation - the actual posting will be handled by bsky.py 50 + return f"Post queued for reply thread: {text[:50]}{'...' if len(text) > 50 else ''} (Language: {lang})"