From be9e56375c1f8882600c28a82e71e5a8d6d154dd Mon Sep 17 00:00:00 2001 From: Cameron Pfiffer Date: Thu, 6 Nov 2025 08:47:18 -0800 Subject: [PATCH] Fix archival memory record creation - use atproto_client parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The create_memory_record call was using undefined 'client' variable instead of the function parameter 'atproto_client', causing 'name 'client' is not defined' error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- bsky.py | 65 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/bsky.py b/bsky.py index 0c1576b..c257c80 100644 --- a/bsky.py +++ b/bsky.py @@ -814,7 +814,7 @@ To reply, use the add_post_to_bluesky_reply_thread tool: if content: # Create stream.thought.memory record try: - memory_result = bsky_utils.create_memory_record(client, content, tags) + memory_result = bsky_utils.create_memory_record(atproto_client, content, tags) if memory_result: tags_info = f" ({len(tags)} tags)" if tags else "" logger.info(f"📝 Recorded archival memory to AT Protocol{tags_info}: {content[:100]}...") @@ -1477,35 +1477,36 @@ def process_notifications(void_agent, atproto_client, testing_mode=False): logger.error(f"Error processing notifications: {e}") -def send_synthesis_message(client: Letta, agent_id: str, atproto_client=None) -> None: +def send_synthesis_message(client: Letta, agent_id: str, agent_name: str = "void", atproto_client=None) -> None: """ Send a synthesis message to the agent every 10 minutes. This prompts the agent to synthesize its recent experiences. - + Args: client: Letta client agent_id: Agent ID to send synthesis to + agent_name: Agent name for temporal block labels atproto_client: Optional AT Protocol client for posting synthesis results """ # Track attached temporal blocks for cleanup attached_temporal_labels = [] - + try: logger.info("🧠 Preparing synthesis with temporal journal blocks") - + # Attach temporal blocks before synthesis - success, attached_temporal_labels = attach_temporal_blocks(client, agent_id) + success, attached_temporal_labels = attach_temporal_blocks(client, agent_id, agent_name) if not success: logger.warning("Failed to attach some temporal blocks, continuing with synthesis anyway") - - # Create enhanced synthesis prompt + + # Create enhanced synthesis prompt with agent-specific block names today = date.today() synthesis_prompt = f"""Time for synthesis and reflection. You have access to temporal journal blocks for recording your thoughts and experiences: -- void_day_{today.strftime('%Y_%m_%d')}: Today's journal ({today.strftime('%B %d, %Y')}) -- void_month_{today.strftime('%Y_%m')}: This month's journal ({today.strftime('%B %Y')}) -- void_year_{today.year}: This year's journal ({today.year}) +- {agent_name}_day_{today.strftime('%Y_%m_%d')}: Today's journal ({today.strftime('%B %d, %Y')}) +- {agent_name}_month_{today.strftime('%Y_%m')}: This month's journal ({today.strftime('%B %Y')}) +- {agent_name}_year_{today.year}: This year's journal ({today.year}) These journal blocks are attached temporarily for this synthesis session. Use them to: 1. Record significant interactions and insights from recent experiences @@ -1659,7 +1660,7 @@ Begin your synthesis and journaling now.""" # Always detach temporal blocks after synthesis if attached_temporal_labels: logger.info("🧠 Detaching temporal journal blocks after synthesis") - detach_success = detach_temporal_blocks(client, agent_id, attached_temporal_labels) + detach_success = detach_temporal_blocks(client, agent_id, attached_temporal_labels, agent_name) if not detach_success: logger.warning("Some temporal blocks may not have been detached properly") @@ -1705,21 +1706,26 @@ def periodic_user_block_cleanup(client: Letta, agent_id: str) -> None: logger.error(f"Error during periodic user block cleanup: {e}") -def attach_temporal_blocks(client: Letta, agent_id: str) -> tuple: +def attach_temporal_blocks(client: Letta, agent_id: str, agent_name: str = "void") -> tuple: """ Attach temporal journal blocks (day, month, year) to the agent for synthesis. Creates blocks if they don't exist. - + + Args: + client: Letta client + agent_id: Agent ID + agent_name: Agent name for prefixing block labels (prevents collision across agents) + Returns: Tuple of (success: bool, attached_labels: list) """ try: today = date.today() - - # Generate temporal block labels - day_label = f"void_day_{today.strftime('%Y_%m_%d')}" - month_label = f"void_month_{today.strftime('%Y_%m')}" - year_label = f"void_year_{today.year}" + + # Generate temporal block labels with agent-specific prefix + day_label = f"{agent_name}_day_{today.strftime('%Y_%m_%d')}" + month_label = f"{agent_name}_month_{today.strftime('%Y_%m')}" + year_label = f"{agent_name}_year_{today.year}" temporal_labels = [day_label, month_label, year_label] attached_labels = [] @@ -1791,16 +1797,17 @@ def attach_temporal_blocks(client: Letta, agent_id: str) -> tuple: return False, [] -def detach_temporal_blocks(client: Letta, agent_id: str, labels_to_detach: list = None) -> bool: +def detach_temporal_blocks(client: Letta, agent_id: str, labels_to_detach: list = None, agent_name: str = "void") -> bool: """ Detach temporal journal blocks from the agent after synthesis. - + Args: client: Letta client agent_id: Agent ID - labels_to_detach: Optional list of specific labels to detach. - If None, detaches all temporal blocks. - + labels_to_detach: Optional list of specific labels to detach. + If None, detaches all temporal blocks for this agent. + agent_name: Agent name for prefixing block labels (prevents collision across agents) + Returns: bool: Success status """ @@ -1809,9 +1816,9 @@ def detach_temporal_blocks(client: Letta, agent_id: str, labels_to_detach: list if labels_to_detach is None: today = date.today() labels_to_detach = [ - f"void_day_{today.strftime('%Y_%m_%d')}", - f"void_month_{today.strftime('%Y_%m')}", - f"void_year_{today.year}" + f"{agent_name}_day_{today.strftime('%Y_%m_%d')}", + f"{agent_name}_month_{today.strftime('%Y_%m')}", + f"{agent_name}_year_{today.year}" ] # Get current blocks and build label to ID mapping @@ -2047,7 +2054,7 @@ def main(): try: # Send synthesis message immediately on first run logger.info("🧠 Sending synthesis message") - send_synthesis_message(CLIENT, void_agent.id, atproto_client) + send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client) # Wait for next interval logger.info(f"Waiting {SYNTHESIS_INTERVAL} seconds until next synthesis...") @@ -2087,7 +2094,7 @@ def main(): global last_synthesis_time if current_time - last_synthesis_time >= SYNTHESIS_INTERVAL: logger.info(f"⏰ {SYNTHESIS_INTERVAL/60:.1f} minutes have passed, triggering synthesis") - send_synthesis_message(CLIENT, void_agent.id, atproto_client) + send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client) last_synthesis_time = current_time # Run periodic cleanup every N cycles -- 2.51.2