a digital person for bluesky

Add environment variable support and --config flag to register_tools.py

- Automatically set BSKY_USERNAME, BSKY_PASSWORD, and PDS_URI as tool execution environment variables on the agent
- Add --config flag to register_tools.py for multi-agent support
- Add --no-env flag to skip environment variable configuration
- Simplify config handling by removing global variables
- Update documentation with new usage examples

This allows tools to access Bluesky credentials when running on Letta's cloud servers, and enables registering tools for different agents with their respective configs.

Usage:
python register_tools.py --config herald.yaml

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

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

Changed files
+54 -7
+13 -1
CLAUDE.md
··· 18 18 # OR 19 19 source .venv/bin/activate && python bsky.py 20 20 21 + # Run with custom config file 22 + ac && python bsky.py --config herald.yaml 23 + 21 24 # Run with testing mode (no messages sent, queue preserved) 22 25 ac && python bsky.py --test 23 26 ··· 46 49 ### Managing Tools 47 50 48 51 ```bash 49 - # Register all tools with void agent (uses agent_id from config) 52 + # Register all tools with void agent (uses agent_id from config.yaml) 50 53 ac && python register_tools.py 54 + 55 + # Register tools for herald agent (uses herald.yaml config) 56 + ac && python register_tools.py --config herald.yaml 51 57 52 58 # Register specific tools 53 59 ac && python register_tools.py --tools search_bluesky_posts post_to_bluesky ··· 57 63 58 64 # Register tools with a different agent by ID 59 65 ac && python register_tools.py --agent-id <agent-id> 66 + 67 + # Register tools without setting environment variables 68 + ac && python register_tools.py --no-env 69 + 70 + # Note: register_tools.py automatically sets BSKY_USERNAME, BSKY_PASSWORD, and PDS_URI 71 + # as environment variables on the agent for tool execution 60 72 ``` 61 73 62 74 ### Managing X Bot
+41 -6
register_tools.py
··· 7 7 from letta_client import Letta 8 8 from rich.console import Console 9 9 from rich.table import Table 10 - from config_loader import get_letta_config 10 + from config_loader import get_letta_config, get_bluesky_config, get_config 11 11 12 12 # Import standalone functions and their schemas 13 13 from tools.search import search_bluesky_posts, SearchArgs ··· 22 22 from tools.webpage import fetch_webpage, WebpageArgs 23 23 from tools.flag_memory_deletion import flag_archival_memory_for_deletion, FlagArchivalMemoryForDeletionArgs 24 24 25 - letta_config = get_letta_config() 26 25 logging.basicConfig(level=logging.INFO) 27 26 logger = logging.getLogger(__name__) 28 27 console = Console() ··· 125 124 ] 126 125 127 126 128 - def register_tools(agent_id: str = None, tools: List[str] = None): 127 + def register_tools(agent_id: str = None, tools: List[str] = None, set_env: bool = True): 129 128 """Register tools with a Letta agent. 130 129 131 130 Args: 132 131 agent_id: ID of the agent to attach tools to. If None, uses config default. 133 132 tools: List of tool names to register. If None, registers all tools. 133 + set_env: If True, set environment variables for tool execution. Defaults to True. 134 134 """ 135 + # Load config fresh (uses global config instance from get_config()) 136 + letta_config = get_letta_config() 137 + 135 138 # Use agent ID from config if not provided 136 139 if agent_id is None: 137 140 agent_id = letta_config['agent_id'] 138 - 141 + 139 142 try: 140 143 # Initialize Letta client with API key and base_url from config 141 144 client_params = { ··· 154 157 console.print(f"Error details: {e}") 155 158 return 156 159 160 + # Set environment variables for tool execution if requested 161 + if set_env: 162 + try: 163 + bsky_config = get_bluesky_config() 164 + env_vars = { 165 + 'BSKY_USERNAME': bsky_config['username'], 166 + 'BSKY_PASSWORD': bsky_config['password'], 167 + 'PDS_URI': bsky_config['pds_uri'] 168 + } 169 + 170 + console.print(f"\n[bold cyan]Setting tool execution environment variables:[/bold cyan]") 171 + console.print(f" BSKY_USERNAME: {env_vars['BSKY_USERNAME']}") 172 + console.print(f" PDS_URI: {env_vars['PDS_URI']}") 173 + console.print(f" BSKY_PASSWORD: {'*' * len(env_vars['BSKY_PASSWORD'])}\n") 174 + 175 + # Modify agent with environment variables 176 + client.agents.modify( 177 + agent_id=agent_id, 178 + tool_exec_environment_variables=env_vars 179 + ) 180 + 181 + console.print("[green]✓ Environment variables set successfully[/green]\n") 182 + except Exception as e: 183 + console.print(f"[yellow]Warning: Failed to set environment variables: {e}[/yellow]\n") 184 + logger.warning(f"Failed to set environment variables: {e}") 185 + 157 186 # Filter tools if specific ones requested 158 187 tools_to_register = TOOL_CONFIGS 159 188 if tools: ··· 228 257 import argparse 229 258 230 259 parser = argparse.ArgumentParser(description="Register Void tools with a Letta agent") 260 + parser.add_argument("--config", type=str, default='config.yaml', help="Path to config file (default: config.yaml)") 231 261 parser.add_argument("--agent-id", help=f"Agent ID (default: from config)") 232 262 parser.add_argument("--tools", nargs="+", help="Specific tools to register (default: all)") 233 263 parser.add_argument("--list", action="store_true", help="List available tools") 264 + parser.add_argument("--no-env", action="store_true", help="Skip setting environment variables") 234 265 235 266 args = parser.parse_args() 267 + 268 + # Initialize config with custom path (sets global config instance) 269 + get_config(args.config) 236 270 237 271 if args.list: 238 272 list_available_tools() 239 273 else: 240 - # Use config default if no agent specified 274 + # Load config and get agent ID 275 + letta_config = get_letta_config() 241 276 agent_id = args.agent_id if args.agent_id else letta_config['agent_id'] 242 277 console.print(f"\n[bold]Registering tools for agent: {agent_id}[/bold]\n") 243 - register_tools(agent_id, args.tools) 278 + register_tools(agent_id, args.tools, set_env=not args.no_env)