this repo has no description

Adjust post thread parent height from 80 to 60 Reduce post thread parent height to 60

+71 -72
+1 -1
bsky_utils.py
··· 250 The thread data or None if not found 251 """ 252 try: 253 - thread = client.app.bsky.feed.get_post_thread({'uri': uri, 'parent_height': 80, 'depth': 10}) 254 return thread 255 except Exception as e: 256 logger.error(f"Error fetching post thread: {e}")
··· 250 The thread data or None if not found 251 """ 252 try: 253 + thread = client.app.bsky.feed.get_post_thread({'uri': uri, 'parent_height': 60, 'depth': 10}) 254 return thread 255 except Exception as e: 256 logger.error(f"Error fetching post thread: {e}")
+26 -26
register_tools.py
··· 16 get_bluesky_feed, 17 attach_user_blocks, 18 detach_user_blocks, 19 - update_user_blocks, 20 ) 21 22 # Import Pydantic models for args_schema 23 from tools.search import SearchArgs 24 from tools.post import PostArgs 25 from tools.feed import FeedArgs 26 - from tools.blocks import AttachUserBlockArgs, DetachUserBlockArgs, UpdateUserBlockArgs 27 28 load_dotenv() 29 logging.basicConfig(level=logging.INFO) ··· 63 "description": "Detach user-specific memory blocks from the agent. Blocks are preserved for later use.", 64 "tags": ["memory", "blocks", "user"] 65 }, 66 - { 67 - "func": update_user_blocks, 68 - "args_schema": UpdateUserBlockArgs, 69 - "description": "Update the content of user-specific memory blocks", 70 - "tags": ["memory", "blocks", "user"] 71 - }, 72 ] 73 74 75 def register_tools(agent_name: str = "void", tools: List[str] = None): 76 """Register tools with a Letta agent. 77 - 78 Args: 79 agent_name: Name of the agent to attach tools to 80 tools: List of tool names to register. If None, registers all tools. ··· 82 try: 83 # Initialize Letta client with API key 84 client = Letta(token=os.environ["LETTA_API_KEY"]) 85 - 86 # Find the agent 87 agents = client.agents.list() 88 agent = None ··· 90 if a.name == agent_name: 91 agent = a 92 break 93 - 94 if not agent: 95 console.print(f"[red]Error: Agent '{agent_name}' not found[/red]") 96 console.print("\nAvailable agents:") 97 for a in agents: 98 console.print(f" - {a.name}") 99 return 100 - 101 # Filter tools if specific ones requested 102 tools_to_register = TOOL_CONFIGS 103 if tools: ··· 105 if len(tools_to_register) != len(tools): 106 missing = set(tools) - {t["func"].__name__ for t in tools_to_register} 107 console.print(f"[yellow]Warning: Unknown tools: {missing}[/yellow]") 108 - 109 # Create results table 110 table = Table(title=f"Tool Registration for Agent '{agent_name}'") 111 table.add_column("Tool", style="cyan") 112 table.add_column("Status", style="green") 113 table.add_column("Description") 114 - 115 # Register each tool 116 for tool_config in tools_to_register: 117 func = tool_config["func"] 118 tool_name = func.__name__ 119 - 120 try: 121 # Create or update the tool using the standalone function 122 created_tool = client.tools.upsert_from_function( ··· 124 args_schema=tool_config["args_schema"], 125 tags=tool_config["tags"] 126 ) 127 - 128 # Get current agent tools 129 current_tools = client.agents.tools.list(agent_id=str(agent.id)) 130 tool_names = [t.name for t in current_tools] 131 - 132 # Check if already attached 133 if created_tool.name in tool_names: 134 table.add_row(tool_name, "Already Attached", tool_config["description"]) ··· 139 tool_id=str(created_tool.id) 140 ) 141 table.add_row(tool_name, "✓ Attached", tool_config["description"]) 142 - 143 except Exception as e: 144 table.add_row(tool_name, f"✗ Error: {str(e)}", tool_config["description"]) 145 logger.error(f"Error registering tool {tool_name}: {e}") 146 - 147 console.print(table) 148 - 149 except Exception as e: 150 console.print(f"[red]Error: {str(e)}[/red]") 151 logger.error(f"Fatal error: {e}") ··· 157 table.add_column("Tool Name", style="cyan") 158 table.add_column("Description") 159 table.add_column("Tags", style="dim") 160 - 161 for tool_config in TOOL_CONFIGS: 162 table.add_row( 163 tool_config["func"].__name__, 164 tool_config["description"], 165 ", ".join(tool_config["tags"]) 166 ) 167 - 168 console.print(table) 169 170 171 if __name__ == "__main__": 172 import argparse 173 - 174 parser = argparse.ArgumentParser(description="Register Void tools with a Letta agent") 175 parser.add_argument("agent", nargs="?", default="void", help="Agent name (default: void)") 176 parser.add_argument("--tools", nargs="+", help="Specific tools to register (default: all)") 177 parser.add_argument("--list", action="store_true", help="List available tools") 178 - 179 args = parser.parse_args() 180 - 181 if args.list: 182 list_available_tools() 183 else: 184 console.print(f"\n[bold]Registering tools for agent: {args.agent}[/bold]\n") 185 - register_tools(args.agent, args.tools)
··· 16 get_bluesky_feed, 17 attach_user_blocks, 18 detach_user_blocks, 19 + # update_user_blocks, 20 ) 21 22 # Import Pydantic models for args_schema 23 from tools.search import SearchArgs 24 from tools.post import PostArgs 25 from tools.feed import FeedArgs 26 + from tools.blocks import AttachUserBlockArgs, DetachUserBlockArgs #, UpdateUserBlockArgs 27 28 load_dotenv() 29 logging.basicConfig(level=logging.INFO) ··· 63 "description": "Detach user-specific memory blocks from the agent. Blocks are preserved for later use.", 64 "tags": ["memory", "blocks", "user"] 65 }, 66 + # { 67 + # "func": update_user_blocks, 68 + # "args_schema": UpdateUserBlockArgs, 69 + # "description": "Update the content of user-specific memory blocks", 70 + # "tags": ["memory", "blocks", "user"] 71 + # }, 72 ] 73 74 75 def register_tools(agent_name: str = "void", tools: List[str] = None): 76 """Register tools with a Letta agent. 77 + 78 Args: 79 agent_name: Name of the agent to attach tools to 80 tools: List of tool names to register. If None, registers all tools. ··· 82 try: 83 # Initialize Letta client with API key 84 client = Letta(token=os.environ["LETTA_API_KEY"]) 85 + 86 # Find the agent 87 agents = client.agents.list() 88 agent = None ··· 90 if a.name == agent_name: 91 agent = a 92 break 93 + 94 if not agent: 95 console.print(f"[red]Error: Agent '{agent_name}' not found[/red]") 96 console.print("\nAvailable agents:") 97 for a in agents: 98 console.print(f" - {a.name}") 99 return 100 + 101 # Filter tools if specific ones requested 102 tools_to_register = TOOL_CONFIGS 103 if tools: ··· 105 if len(tools_to_register) != len(tools): 106 missing = set(tools) - {t["func"].__name__ for t in tools_to_register} 107 console.print(f"[yellow]Warning: Unknown tools: {missing}[/yellow]") 108 + 109 # Create results table 110 table = Table(title=f"Tool Registration for Agent '{agent_name}'") 111 table.add_column("Tool", style="cyan") 112 table.add_column("Status", style="green") 113 table.add_column("Description") 114 + 115 # Register each tool 116 for tool_config in tools_to_register: 117 func = tool_config["func"] 118 tool_name = func.__name__ 119 + 120 try: 121 # Create or update the tool using the standalone function 122 created_tool = client.tools.upsert_from_function( ··· 124 args_schema=tool_config["args_schema"], 125 tags=tool_config["tags"] 126 ) 127 + 128 # Get current agent tools 129 current_tools = client.agents.tools.list(agent_id=str(agent.id)) 130 tool_names = [t.name for t in current_tools] 131 + 132 # Check if already attached 133 if created_tool.name in tool_names: 134 table.add_row(tool_name, "Already Attached", tool_config["description"]) ··· 139 tool_id=str(created_tool.id) 140 ) 141 table.add_row(tool_name, "✓ Attached", tool_config["description"]) 142 + 143 except Exception as e: 144 table.add_row(tool_name, f"✗ Error: {str(e)}", tool_config["description"]) 145 logger.error(f"Error registering tool {tool_name}: {e}") 146 + 147 console.print(table) 148 + 149 except Exception as e: 150 console.print(f"[red]Error: {str(e)}[/red]") 151 logger.error(f"Fatal error: {e}") ··· 157 table.add_column("Tool Name", style="cyan") 158 table.add_column("Description") 159 table.add_column("Tags", style="dim") 160 + 161 for tool_config in TOOL_CONFIGS: 162 table.add_row( 163 tool_config["func"].__name__, 164 tool_config["description"], 165 ", ".join(tool_config["tags"]) 166 ) 167 + 168 console.print(table) 169 170 171 if __name__ == "__main__": 172 import argparse 173 + 174 parser = argparse.ArgumentParser(description="Register Void tools with a Letta agent") 175 parser.add_argument("agent", nargs="?", default="void", help="Agent name (default: void)") 176 parser.add_argument("--tools", nargs="+", help="Specific tools to register (default: all)") 177 parser.add_argument("--list", action="store_true", help="List available tools") 178 + 179 args = parser.parse_args() 180 + 181 if args.list: 182 list_available_tools() 183 else: 184 console.print(f"\n[bold]Registering tools for agent: {args.agent}[/bold]\n") 185 + register_tools(args.agent, args.tools)
+44 -45
tools/blocks.py
··· 63 client.agents.blocks.attach( 64 agent_id=str(agent_state.id), 65 block_id=str(block.id), 66 - enable_sleeptime=False, 67 ) 68 results.append(f"✓ {handle}: Block attached") 69 ··· 132 return f"Error detaching user blocks: {str(e)}" 133 134 135 - class UserBlockUpdate(BaseModel): 136 - handle: str = Field(..., description="User's Bluesky handle (e.g., 'user.bsky.social')") 137 - content: str = Field(..., description="New content for the user's memory block") 138 139 140 - class UpdateUserBlockArgs(BaseModel): 141 - updates: List[UserBlockUpdate] = Field(..., description="List of user block updates") 142 143 144 - class UpdateUserBlockTool(BaseTool): 145 - name: str = "update_user_blocks" 146 - args_schema: Type[BaseModel] = UpdateUserBlockArgs 147 - description: str = "Update the content of user-specific memory blocks" 148 - tags: List[str] = ["memory", "blocks", "user"] 149 150 - def run(self, updates: List[UserBlockUpdate]) -> str: 151 - """Update user-specific memory blocks.""" 152 - import os 153 - from letta_client import Letta 154 155 - try: 156 - client = Letta(token=os.environ["LETTA_API_KEY"]) 157 - results = [] 158 159 - for update in updates: 160 - handle = update.handle 161 - new_content = update.content 162 - # Sanitize handle for block label - completely self-contained 163 - clean_handle = handle.lstrip('@').replace('.', '_').replace('-', '_').replace(' ', '_') 164 - block_label = f"user_{clean_handle}" 165 166 - try: 167 - # Find the block 168 - blocks = client.blocks.list(label=block_label) 169 - if not blocks or len(blocks) == 0: 170 - results.append(f"✗ {handle}: Block not found - use attach_user_blocks first") 171 - continue 172 173 - block = blocks[0] 174 175 - # Update block content 176 - updated_block = client.blocks.modify( 177 - block_id=str(block.id), 178 - value=new_content 179 - ) 180 181 - preview = new_content[:100] + "..." if len(new_content) > 100 else new_content 182 - results.append(f"✓ {handle}: Updated - {preview}") 183 184 - except Exception as e: 185 - results.append(f"✗ {handle}: Error - {str(e)}") 186 - logger.error(f"Error updating block for {handle}: {e}") 187 188 - return f"Update results:\n" + "\n".join(results) 189 190 - except Exception as e: 191 - logger.error(f"Error updating user blocks: {e}") 192 - return f"Error updating user blocks: {str(e)}"
··· 63 client.agents.blocks.attach( 64 agent_id=str(agent_state.id), 65 block_id=str(block.id), 66 ) 67 results.append(f"✓ {handle}: Block attached") 68 ··· 131 return f"Error detaching user blocks: {str(e)}" 132 133 134 + # class UserBlockUpdate(BaseModel): 135 + # handle: str = Field(..., description="User's Bluesky handle (e.g., 'user.bsky.social')") 136 + # content: str = Field(..., description="New content for the user's memory block") 137 138 139 + # class UpdateUserBlockArgs(BaseModel): 140 + # updates: List[UserBlockUpdate] = Field(..., description="List of user block updates") 141 142 143 + # class UpdateUserBlockTool(BaseTool): 144 + # name: str = "update_user_blocks" 145 + # args_schema: Type[BaseModel] = UpdateUserBlockArgs 146 + # description: str = "Update the content of user-specific memory blocks" 147 + # tags: List[str] = ["memory", "blocks", "user"] 148 149 + # def run(self, updates: List[UserBlockUpdate]) -> str: 150 + # """Update user-specific memory blocks.""" 151 + # import os 152 + # from letta_client import Letta 153 154 + # try: 155 + # client = Letta(token=os.environ["LETTA_API_KEY"]) 156 + # results = [] 157 158 + # for update in updates: 159 + # handle = update.handle 160 + # new_content = update.content 161 + # # Sanitize handle for block label - completely self-contained 162 + # clean_handle = handle.lstrip('@').replace('.', '_').replace('-', '_').replace(' ', '_') 163 + # block_label = f"user_{clean_handle}" 164 165 + # try: 166 + # # Find the block 167 + # blocks = client.blocks.list(label=block_label) 168 + # if not blocks or len(blocks) == 0: 169 + # results.append(f"✗ {handle}: Block not found - use attach_user_blocks first") 170 + # continue 171 172 + # block = blocks[0] 173 174 + # # Update block content 175 + # updated_block = client.blocks.modify( 176 + # block_id=str(block.id), 177 + # value=new_content 178 + # ) 179 180 + # preview = new_content[:100] + "..." if len(new_content) > 100 else new_content 181 + # results.append(f"✓ {handle}: Updated - {preview}") 182 183 + # except Exception as e: 184 + # results.append(f"✗ {handle}: Error - {str(e)}") 185 + # logger.error(f"Error updating block for {handle}: {e}") 186 187 + # return f"Update results:\n" + "\n".join(results) 188 189 + # except Exception as e: 190 + # logger.error(f"Error updating user blocks: {e}") 191 + # return f"Error updating user blocks: {str(e)}"