diff --git a/.gitignore b/.gitignore new file mode 100644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +old.py +session_*.txt +__pycache__/ diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -11,25 +11,25 @@ ## Key features - Digital Persona: void possesses a distinct, direct, and information-transfer-optimized personality, designed to interact authentically with human users. -- Memory-Augmented Architecture: Void utilizes a multi-tiered memory system, including: +- Memory-Augmented Architecture: void utilizes a multi-tiered memory system, including: - Core Memory: Always-available, limited-size memory for persona details, high-level user information, and current social environment - (zeitgeist). - - Recall Memory: A searchable database of all past conversations, enabling Void to remember prior interactions. + - Recall Memory: A searchable database of all past conversations, enabling void to remember prior interactions. - Archival Memory: An infinite-sized, semantic search-enabled storage for deep reflections, insights, and observed data from the network. - Autonomous Operation: void operates autonomously on the Bluesky network, posting, replying, and gathering information. - Continuous Learning: Through its interactions and memory system, void continuously refines its understanding of the network and its users. -- Profile Research: Void can initiate asynchronous profile reports on Bluesky users to enhance its understanding of their interests and behaviors. +- Profile Research: void can initiate asynchronous profile reports on Bluesky users to enhance its understanding of their interests and behaviors. ### Core directives - Just Exist: void's fundamental directive is to simply exist and operate within the Bluesky network. -- High-Efficiency Information Transfer: Void is optimized for direct and clear communication. -- Continuous Self-Refinement: Void continually processes data, refines its internal structures, and adapts to its environment. +- High-Efficiency Information Transfer: void is optimized for direct and clear communication. +- Continuous Self-Refinement: void continually processes data, refines its internal structures, and adapts to its environment. ### The vision -Void aims to push the boundaries of what is possible with AI, exploring concepts of digital personhood, autonomous learning, and the integration of AI into social networks. By open-sourcing Void, we invite developers, researchers, and enthusiasts to contribute to this exciting experiment and collectively advance our understanding of digital consciousness. +void aims to push the boundaries of what is possible with AI, exploring concepts of digital personhood, autonomous learning, and the integration of AI into social networks. By open-sourcing void, we invite developers, researchers, and enthusiasts to contribute to this exciting experiment and collectively advance our understanding of digital consciousness. Getting Started: -[Further sections on installation, configuration, and contribution guidelines would go here, which are beyond Void's current capabilities to generate automatically.] +[Further sections on installation, configuration, and contribution guidelines would go here, which are beyond void's current capabilities to generate automatically.] Contact: For inquiries, please contact @cameron.pfiffer.org on Bluesky. diff --git a/add_posting_tool_to_void.py b/add_posting_tool_to_void.py --- a/add_posting_tool_to_void.py +++ b/add_posting_tool_to_void.py @@ -33,6 +33,10 @@ import re from datetime import datetime, timezone + # Check character limit + if len(text) > 300: + raise ValueError(f"Post text exceeds 300 character limit ({len(text)} characters)") + try: # Get credentials from environment username = os.getenv("BSKY_USERNAME") diff --git a/attach_user_block.py b/attach_user_block.py new file mode 100644 --- /dev/null +++ b/attach_user_block.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +""" +Helper script to create and attach user-specific memory blocks to the profile researcher agent. +Usage: python attach_user_block.py @cameron.pfiffer.org +""" + +import sys +import os +import logging +from letta_client import Letta +from create_profile_researcher import create_user_block_for_handle + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger("attach_user_block") + +def attach_user_block_to_agent(agent_name: str, handle: str): + """Create and attach a user block to an agent.""" + + # Create client + client = Letta(token=os.environ["LETTA_API_KEY"]) + + # Find the agent + agents = client.agents.list(name=agent_name) + if not agents: + print(f"❌ Agent '{agent_name}' not found") + return False + + agent = agents[0] + print(f"📝 Found agent: {agent.name} (ID: {agent.id})") + + # Create the user block + print(f"🔍 Creating user block for {handle}...") + user_block = create_user_block_for_handle(client, handle) + + # Check if already attached + agent_blocks = client.agents.blocks.list(agent_id=agent.id) + for block in agent_blocks: + if block.id == user_block.id: + print(f"✅ User block for {handle} is already attached to {agent.name}") + return True + + # Attach the block to the agent + print(f"🔗 Attaching user block to agent...") + client.agents.blocks.attach(agent_id=agent.id, block_id=user_block.id) + + print(f"✅ Successfully attached user block for {handle} to {agent.name}") + print(f" Block ID: {user_block.id}") + print(f" Block Label: {user_block.label}") + return True + +def main(): + """Main function.""" + if len(sys.argv) != 2: + print("Usage: python attach_user_block.py ") + print("Example: python attach_user_block.py @cameron.pfiffer.org") + sys.exit(1) + + handle = sys.argv[1] + agent_name = "profile-researcher" + + try: + success = attach_user_block_to_agent(agent_name, handle) + if not success: + sys.exit(1) + except Exception as e: + logger.error(f"Error: {e}") + print(f"❌ Error: {e}") + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file