a digital person for bluesky

Add comprehensive user memory block management tools

- Add user_note_append: Append text to user memory blocks
- Add user_note_replace: Find and replace text in blocks
- Add user_note_set: Completely set block content
- Add user_note_view: View block content

These tools provide fine-grained control over user-specific
memory blocks, allowing the agent to view, append, replace,
or completely rewrite user information as needed.

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

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

Changed files
+51 -1
tools
+7 -1
register_tools.py
··· 13 13 from tools.search import search_bluesky_posts, SearchArgs 14 14 from tools.post import create_new_bluesky_post, PostArgs 15 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, AttachUserBlocksArgs, DetachUserBlocksArgs, UserNoteAppendArgs, UserNoteReplaceArgs, UserNoteSetArgs 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 17 from tools.reply import bluesky_reply, ReplyArgs 18 18 from tools.halt import halt_activity, HaltArgs 19 19 ··· 72 72 "args_schema": UserNoteSetArgs, 73 73 "description": "Set the complete content of a user's memory block.", 74 74 "tags": ["memory", "blocks", "user", "set"] 75 + }, 76 + { 77 + "func": user_note_view, 78 + "args_schema": UserNoteViewArgs, 79 + "description": "View the content of a user's memory block.", 80 + "tags": ["memory", "blocks", "user", "view"] 75 81 }, 76 82 { 77 83 "func": bluesky_reply,
+44
tools/blocks.py
··· 27 27 content: str = Field(..., description="Complete content to set for the user's memory block") 28 28 29 29 30 + class UserNoteViewArgs(BaseModel): 31 + handle: str = Field(..., description="User Bluesky handle (e.g., 'cameron.pfiffer.org')") 32 + 33 + 30 34 31 35 def attach_user_blocks(handles: list, agent_state: "AgentState") -> str: 32 36 """ ··· 350 354 raise Exception(f"Error setting user block content: {str(e)}") 351 355 352 356 357 + def user_note_view(handle: str, agent_state: "AgentState") -> str: 358 + """ 359 + View the content of a user's memory block. 360 + 361 + Args: 362 + handle: User Bluesky handle (e.g., 'cameron.pfiffer.org') 363 + agent_state: The agent state object containing agent information 364 + 365 + Returns: 366 + String containing the user's memory block content 367 + """ 368 + import os 369 + import logging 370 + from letta_client import Letta 371 + 372 + logger = logging.getLogger(__name__) 373 + 374 + try: 375 + client = Letta(token=os.environ["LETTA_API_KEY"]) 376 + 377 + # Sanitize handle for block label 378 + clean_handle = handle.lstrip('@').replace('.', '_').replace('-', '_').replace(' ', '_') 379 + block_label = f"user_{clean_handle}" 380 + 381 + # Check if block exists 382 + blocks = client.blocks.list(label=block_label) 383 + 384 + if not blocks or len(blocks) == 0: 385 + return f"No memory block found for user: {handle}" 386 + 387 + block = blocks[0] 388 + logger.info(f"Retrieved content for block: {block_label}") 389 + 390 + return f"Memory block for {handle}:\n\n{block.value}" 391 + 392 + except Exception as e: 393 + logger.error(f"Error viewing user block: {e}") 394 + raise Exception(f"Error viewing user block: {str(e)}") 395 + 396 +