a digital person for bluesky

Fix archival memory record creation - use atproto_client parameter

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 <noreply@anthropic.com>

+36 -29
+36 -29
bsky.py
··· 814 if content: 815 # Create stream.thought.memory record 816 try: 817 - memory_result = bsky_utils.create_memory_record(client, content, tags) 818 if memory_result: 819 tags_info = f" ({len(tags)} tags)" if tags else "" 820 logger.info(f"📝 Recorded archival memory to AT Protocol{tags_info}: {content[:100]}...") ··· 1477 logger.error(f"Error processing notifications: {e}") 1478 1479 1480 - def send_synthesis_message(client: Letta, agent_id: str, atproto_client=None) -> None: 1481 """ 1482 Send a synthesis message to the agent every 10 minutes. 1483 This prompts the agent to synthesize its recent experiences. 1484 - 1485 Args: 1486 client: Letta client 1487 agent_id: Agent ID to send synthesis to 1488 atproto_client: Optional AT Protocol client for posting synthesis results 1489 """ 1490 # Track attached temporal blocks for cleanup 1491 attached_temporal_labels = [] 1492 - 1493 try: 1494 logger.info("🧠 Preparing synthesis with temporal journal blocks") 1495 - 1496 # Attach temporal blocks before synthesis 1497 - success, attached_temporal_labels = attach_temporal_blocks(client, agent_id) 1498 if not success: 1499 logger.warning("Failed to attach some temporal blocks, continuing with synthesis anyway") 1500 - 1501 - # Create enhanced synthesis prompt 1502 today = date.today() 1503 synthesis_prompt = f"""Time for synthesis and reflection. 1504 1505 You have access to temporal journal blocks for recording your thoughts and experiences: 1506 - - void_day_{today.strftime('%Y_%m_%d')}: Today's journal ({today.strftime('%B %d, %Y')}) 1507 - - void_month_{today.strftime('%Y_%m')}: This month's journal ({today.strftime('%B %Y')}) 1508 - - void_year_{today.year}: This year's journal ({today.year}) 1509 1510 These journal blocks are attached temporarily for this synthesis session. Use them to: 1511 1. Record significant interactions and insights from recent experiences ··· 1659 # Always detach temporal blocks after synthesis 1660 if attached_temporal_labels: 1661 logger.info("🧠 Detaching temporal journal blocks after synthesis") 1662 - detach_success = detach_temporal_blocks(client, agent_id, attached_temporal_labels) 1663 if not detach_success: 1664 logger.warning("Some temporal blocks may not have been detached properly") 1665 ··· 1705 logger.error(f"Error during periodic user block cleanup: {e}") 1706 1707 1708 - def attach_temporal_blocks(client: Letta, agent_id: str) -> tuple: 1709 """ 1710 Attach temporal journal blocks (day, month, year) to the agent for synthesis. 1711 Creates blocks if they don't exist. 1712 - 1713 Returns: 1714 Tuple of (success: bool, attached_labels: list) 1715 """ 1716 try: 1717 today = date.today() 1718 - 1719 - # Generate temporal block labels 1720 - day_label = f"void_day_{today.strftime('%Y_%m_%d')}" 1721 - month_label = f"void_month_{today.strftime('%Y_%m')}" 1722 - year_label = f"void_year_{today.year}" 1723 1724 temporal_labels = [day_label, month_label, year_label] 1725 attached_labels = [] ··· 1791 return False, [] 1792 1793 1794 - def detach_temporal_blocks(client: Letta, agent_id: str, labels_to_detach: list = None) -> bool: 1795 """ 1796 Detach temporal journal blocks from the agent after synthesis. 1797 - 1798 Args: 1799 client: Letta client 1800 agent_id: Agent ID 1801 - labels_to_detach: Optional list of specific labels to detach. 1802 - If None, detaches all temporal blocks. 1803 - 1804 Returns: 1805 bool: Success status 1806 """ ··· 1809 if labels_to_detach is None: 1810 today = date.today() 1811 labels_to_detach = [ 1812 - f"void_day_{today.strftime('%Y_%m_%d')}", 1813 - f"void_month_{today.strftime('%Y_%m')}", 1814 - f"void_year_{today.year}" 1815 ] 1816 1817 # Get current blocks and build label to ID mapping ··· 2047 try: 2048 # Send synthesis message immediately on first run 2049 logger.info("🧠 Sending synthesis message") 2050 - send_synthesis_message(CLIENT, void_agent.id, atproto_client) 2051 2052 # Wait for next interval 2053 logger.info(f"Waiting {SYNTHESIS_INTERVAL} seconds until next synthesis...") ··· 2087 global last_synthesis_time 2088 if current_time - last_synthesis_time >= SYNTHESIS_INTERVAL: 2089 logger.info(f"⏰ {SYNTHESIS_INTERVAL/60:.1f} minutes have passed, triggering synthesis") 2090 - send_synthesis_message(CLIENT, void_agent.id, atproto_client) 2091 last_synthesis_time = current_time 2092 2093 # Run periodic cleanup every N cycles
··· 814 if content: 815 # Create stream.thought.memory record 816 try: 817 + memory_result = bsky_utils.create_memory_record(atproto_client, content, tags) 818 if memory_result: 819 tags_info = f" ({len(tags)} tags)" if tags else "" 820 logger.info(f"📝 Recorded archival memory to AT Protocol{tags_info}: {content[:100]}...") ··· 1477 logger.error(f"Error processing notifications: {e}") 1478 1479 1480 + def send_synthesis_message(client: Letta, agent_id: str, agent_name: str = "void", atproto_client=None) -> None: 1481 """ 1482 Send a synthesis message to the agent every 10 minutes. 1483 This prompts the agent to synthesize its recent experiences. 1484 + 1485 Args: 1486 client: Letta client 1487 agent_id: Agent ID to send synthesis to 1488 + agent_name: Agent name for temporal block labels 1489 atproto_client: Optional AT Protocol client for posting synthesis results 1490 """ 1491 # Track attached temporal blocks for cleanup 1492 attached_temporal_labels = [] 1493 + 1494 try: 1495 logger.info("🧠 Preparing synthesis with temporal journal blocks") 1496 + 1497 # Attach temporal blocks before synthesis 1498 + success, attached_temporal_labels = attach_temporal_blocks(client, agent_id, agent_name) 1499 if not success: 1500 logger.warning("Failed to attach some temporal blocks, continuing with synthesis anyway") 1501 + 1502 + # Create enhanced synthesis prompt with agent-specific block names 1503 today = date.today() 1504 synthesis_prompt = f"""Time for synthesis and reflection. 1505 1506 You have access to temporal journal blocks for recording your thoughts and experiences: 1507 + - {agent_name}_day_{today.strftime('%Y_%m_%d')}: Today's journal ({today.strftime('%B %d, %Y')}) 1508 + - {agent_name}_month_{today.strftime('%Y_%m')}: This month's journal ({today.strftime('%B %Y')}) 1509 + - {agent_name}_year_{today.year}: This year's journal ({today.year}) 1510 1511 These journal blocks are attached temporarily for this synthesis session. Use them to: 1512 1. Record significant interactions and insights from recent experiences ··· 1660 # Always detach temporal blocks after synthesis 1661 if attached_temporal_labels: 1662 logger.info("🧠 Detaching temporal journal blocks after synthesis") 1663 + detach_success = detach_temporal_blocks(client, agent_id, attached_temporal_labels, agent_name) 1664 if not detach_success: 1665 logger.warning("Some temporal blocks may not have been detached properly") 1666 ··· 1706 logger.error(f"Error during periodic user block cleanup: {e}") 1707 1708 1709 + def attach_temporal_blocks(client: Letta, agent_id: str, agent_name: str = "void") -> tuple: 1710 """ 1711 Attach temporal journal blocks (day, month, year) to the agent for synthesis. 1712 Creates blocks if they don't exist. 1713 + 1714 + Args: 1715 + client: Letta client 1716 + agent_id: Agent ID 1717 + agent_name: Agent name for prefixing block labels (prevents collision across agents) 1718 + 1719 Returns: 1720 Tuple of (success: bool, attached_labels: list) 1721 """ 1722 try: 1723 today = date.today() 1724 + 1725 + # Generate temporal block labels with agent-specific prefix 1726 + day_label = f"{agent_name}_day_{today.strftime('%Y_%m_%d')}" 1727 + month_label = f"{agent_name}_month_{today.strftime('%Y_%m')}" 1728 + year_label = f"{agent_name}_year_{today.year}" 1729 1730 temporal_labels = [day_label, month_label, year_label] 1731 attached_labels = [] ··· 1797 return False, [] 1798 1799 1800 + def detach_temporal_blocks(client: Letta, agent_id: str, labels_to_detach: list = None, agent_name: str = "void") -> bool: 1801 """ 1802 Detach temporal journal blocks from the agent after synthesis. 1803 + 1804 Args: 1805 client: Letta client 1806 agent_id: Agent ID 1807 + labels_to_detach: Optional list of specific labels to detach. 1808 + If None, detaches all temporal blocks for this agent. 1809 + agent_name: Agent name for prefixing block labels (prevents collision across agents) 1810 + 1811 Returns: 1812 bool: Success status 1813 """ ··· 1816 if labels_to_detach is None: 1817 today = date.today() 1818 labels_to_detach = [ 1819 + f"{agent_name}_day_{today.strftime('%Y_%m_%d')}", 1820 + f"{agent_name}_month_{today.strftime('%Y_%m')}", 1821 + f"{agent_name}_year_{today.year}" 1822 ] 1823 1824 # Get current blocks and build label to ID mapping ··· 2054 try: 2055 # Send synthesis message immediately on first run 2056 logger.info("🧠 Sending synthesis message") 2057 + send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client) 2058 2059 # Wait for next interval 2060 logger.info(f"Waiting {SYNTHESIS_INTERVAL} seconds until next synthesis...") ··· 2094 global last_synthesis_time 2095 if current_time - last_synthesis_time >= SYNTHESIS_INTERVAL: 2096 logger.info(f"⏰ {SYNTHESIS_INTERVAL/60:.1f} minutes have passed, triggering synthesis") 2097 + send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client) 2098 last_synthesis_time = current_time 2099 2100 # Run periodic cleanup every N cycles