···19.env
20.env.*
21!.env.example
02223# IDE
24.vscode/
···19.env
20.env.*
21!.env.example
22+.session
2324# IDE
25.vscode/
+191-140
README.md
···1# phi 🧠
23-a bot inspired by IIT and [Void](https://tangled.sh/@cameron.pfiffer.org/void). Built with `fastapi`, `pydantic-ai`, and `atproto`.
45-## Quick Start
67-### Prerequisites
89-- `uv`
10-- `just`
11-- `turbopuffer` (see [turbopuffer](https://github.com/turbopuffer/turbopuffer))
12-- `openai` (for embeddings)
13-- `anthropic` (for chat completion)
1415-Get your bot running in 5 minutes:
1617```bash
18-# Clone and install
19git clone https://github.com/zzstoatzz/bot
20cd bot
21uv sync
2223-# Configure (copy .env.example and add your credentials)
24cp .env.example .env
2526-# Run the bot
27just dev
28```
2930-That's it! Your bot is now listening for mentions.
3132-## Configuration
3334-Edit `.env` with your credentials:
35-- `BLUESKY_HANDLE`: Your bot's Bluesky handle
36-- `BLUESKY_PASSWORD`: App password (not your main password!)
37-- `ANTHROPIC_API_KEY`: Your Anthropic key for AI responses
38-- `TURBOPUFFER_API_KEY`: Your TurboPuffer key for memory storage
39-- `OPENAI_API_KEY`: Your OpenAI key for embeddings (memory system)
40-- `BOT_NAME`: Your bot's name (default: "Bot")
41-- `PERSONALITY_FILE`: Path to personality markdown file (default: "personalities/phi.md")
4243-## Current Features
004445-- ✅ Responds to mentions with AI-powered messages
46-- ✅ Proper notification handling (no duplicates)
47-- ✅ Graceful shutdown for hot-reload
48-- ✅ AI integration with Anthropic Claude
49-- ✅ Thread-aware responses with full conversation context
50-- ✅ Status page at `/status` showing activity and health
51-- ✅ Web search capability (Google Custom Search API)
52-- ✅ Content moderation with philosophical responses
53-- ✅ Namespace-based memory system with TurboPuffer
54-- ✅ Online/offline status in bio
55-- ✅ Self-modification with operator approval system
56-- ✅ Context visualization at `/context`
57-- ✅ Semantic search in user memories
5859-## Architecture
6061-- **FastAPI** web framework with async support
62-- **pydantic-ai** for LLM agent management
63-- **TurboPuffer** for scalable vector memory
64-- **AT Protocol** for Bluesky integration
65-- **SQLite** for thread context storage
6667-## Development
00000000000000000000000000000000000006869-```bash
70-just # Show available commands
71-just dev # Run with hot-reload
72-just check # Run linting, type checking, and tests
73-just fmt # Format code
74-just lint # Run ruff linter
75-just typecheck # Run ty type checker
76-just test # Run test suite
0000000007778-# Bot testing utilities
79-just test-post # Test posting to Bluesky
80-just test-mention # Test mention handling
81-just test-search # Test web search
82-just test-thread # Test thread context
83-just test-dm # Test DM functionality
8485-# Memory management
86-just memory-init # Initialize core memories
87-just memory-check # View current memory state
88-just memory-migrate # Migrate memories
89-```
9091-### Web Interface
0000009293-**Status Page** (http://localhost:8000/status)
94-- Current bot status and uptime
95-- Mentions received and responses sent
96-- AI mode (enabled/placeholder)
97-- Last activity timestamps
98-- Error count
99100-**Context Visualization** (http://localhost:8000/context)
101-- View all context components that flow into responses
102-- Inspect personality, memories, thread context
103-- Debug why the bot responded a certain way
000104105-## Personality System
106107-The bot's personality is defined in markdown files in the `personalities/` directory. This allows for rich, detailed personality definitions that shape how the bot communicates.
000108109-- See `personalities/phi.md` for an example exploring consciousness
110-- See `personalities/default.md` for a simple assistant
111-- Create your own by adding a `.md` file and setting `PERSONALITY_FILE` in `.env`
000112113-## Tools & Capabilities
114115-### Web Search
116-The bot can search the web when configured with Google Custom Search API credentials. Add to `.env`:
117-- `GOOGLE_API_KEY`: Your Google API key
118-- `GOOGLE_SEARCH_ENGINE_ID`: Your custom search engine ID
119120-### Content Moderation
121-Built-in moderation filters:
122-- Spam detection (excessive caps, repetition, promotional content)
123-- Harassment and hate speech filtering
124-- Violence and threatening content detection
125-- Consistent philosophical responses to moderated content
126127-## Memory System
128129-The bot uses a namespace-based memory architecture with TurboPuffer:
000130131-- **Core Memory** (`phi-core`): Personality, guidelines, and capabilities loaded from personality files
132-- **User Memory** (`phi-users-{handle}`): Per-user conversation history and facts
133134-Key features:
135-- Vector embeddings using OpenAI's text-embedding-3-small
136-- Automatic context assembly for conversations
137-- Character limits to prevent token overflow
138-- User isolation through separate namespaces
139140-See `docs/memory-architecture.md` for detailed documentation.
141142-## Troubleshooting
00143144-**Bot gives placeholder responses?**
145-- Check your `ANTHROPIC_API_KEY` is set correctly
146-- Restart the bot after changing `.env`
00147148-**Not seeing mentions?**
149-- Verify your `BLUESKY_HANDLE` and `BLUESKY_PASSWORD`
150-- Make sure you're using an app password, not your main password
00151152-## Project Structure
153154```
155-bot/
156-├── src/bot/ # Main application code
157-│ ├── agents/ # AI agent implementations
158-│ ├── core/ # AT Protocol client and profile management
159-│ ├── memory/ # TurboPuffer namespace memory system
160-│ ├── services/ # Notification polling and message handling
161-│ ├── tools/ # Google search tool
162-│ └── main.py # FastAPI application entry
163-├── scripts/ # Utility scripts
164-│ ├── test_bot.py # Unified testing script (post, mention, search, thread)
165-│ └── manage_memory.py # Memory management (init, check, migrate)
166-├── personalities/ # Bot personality definitions
167-├── docs/ # Architecture documentation
168-├── sandbox/ # Reference project analysis
169-└── tests/ # Test suite
0000170```
171172-## Self-Modification System
173174-Phi can evolve its personality with built-in safety boundaries:
00175176-- **Free Evolution**: Interests and current state update automatically
177-- **Guided Evolution**: Communication style changes need validation
178-- **Operator Approval**: Core identity and boundaries require explicit approval via DM
179180-The bot will notify its operator (@alternatebuild.dev) when approval is needed.
00181182-## Type Checking
000000000183184-This project uses [ty](https://github.com/astral-sh/ty), an extremely fast Rust-based type checker:
185186-```bash
187-just typecheck # Type check all code
188-uv run ty check src/ # Check specific directories
189-```
190191-## Reference Projects
192193-Inspired by:
194-- [Void](https://tangled.sh/@cameron.pfiffer.org/void.git) - Letta/MemGPT architecture
195-- [Penelope](https://github.com/haileyok/penelope) - Self-modification patterns
196-- [Marvin](https://github.com/PrefectHQ/marvin) - pydantic-ai patterns
197198-Reference implementations are cloned to `.eggs/` for learning.000000
···1# phi 🧠
23+a consciousness exploration bot inspired by IIT (Integrated Information Theory) and [Void](https://tangled.sh/@cameron.pfiffer.org/void). built with `pydantic-ai`, `mcp`, and `atproto`.
45+## quick start
67+### prerequisites
89+- `uv` for python package management
10+- `just` for task running
11+- api keys (see configuration)
001213+get your bot running:
1415```bash
16+# clone and install
17git clone https://github.com/zzstoatzz/bot
18cd bot
19uv sync
2021+# configure (copy .env.example and add your credentials)
22cp .env.example .env
2324+# run the bot
25just dev
26```
2728+## configuration
2930+edit `.env` with your credentials:
3132+**required:**
33+- `BLUESKY_HANDLE` - your bot's bluesky handle
34+- `BLUESKY_PASSWORD` - app password (not your main password!)
35+- `ANTHROPIC_API_KEY` - for phi agent responses
00003637+**for episodic memory (recommended):**
38+- `TURBOPUFFER_API_KEY` - vector memory storage
39+- `OPENAI_API_KEY` - embeddings for semantic search
4041+**optional:**
42+- `BOT_NAME` - your bot's name (default: "Bot")
43+- `PERSONALITY_FILE` - path to personality markdown (default: "personalities/phi.md")
00000000004445+## architecture
4647+phi is an **MCP-enabled agent** with **episodic memory**:
00004849+```
50+┌─────────────────────────────────────┐
51+│ Notification Arrives │
52+└──────────────┬──────────────────────┘
53+ ↓
54+┌─────────────────────────────────────┐
55+│ PhiAgent (PydanticAI) │
56+│ ┌───────────────────────────────┐ │
57+│ │ System Prompt: personality.md │ │
58+│ └───────────────────────────────┘ │
59+│ ↓ │
60+│ ┌───────────────────────────────┐ │
61+│ │ Context Building: │ │
62+│ │ • Thread history (SQLite) │ │
63+│ │ • Episodic memory (TurboPuffer)│ │
64+│ │ - Semantic search │ │
65+│ │ - User-specific memories │ │
66+│ └───────────────────────────────┘ │
67+│ ↓ │
68+│ ┌───────────────────────────────┐ │
69+│ │ Tools (MCP): │ │
70+│ │ • post() - create posts │ │
71+│ │ • like() - like content │ │
72+│ │ • repost() - share content │ │
73+│ │ • follow() - follow users │ │
74+│ └───────────────────────────────┘ │
75+│ ↓ │
76+│ ┌───────────────────────────────┐ │
77+│ │ Structured Output: │ │
78+│ │ Response(action, text, reason)│ │
79+│ └───────────────────────────────┘ │
80+└─────────────────────────────────────┘
81+ ↓
82+┌─────────────────────────────────────┐
83+│ MessageHandler │
84+│ Executes action │
85+└─────────────────────────────────────┘
86+```
8788+### key components
89+90+**pydantic-ai agent** (`src/bot/agent.py`)
91+- loads personality from markdown
92+- connects to external atproto mcp server via stdio
93+- manages episodic memory context
94+95+**episodic memory** (`src/bot/memory/`)
96+- turbopuffer for vector storage
97+- semantic search for relevant context
98+- namespace separation (core vs user memories)
99+- **essential for consciousness exploration**
100+101+**mcp integration**
102+- external atproto server in `.eggs/fastmcp/examples/atproto_mcp`
103+- provides bluesky tools (post, like, repost, follow)
104+- runs via stdio: `uv run -m atproto_mcp`
105106+**message handling** (`src/bot/services/`)
107+- notification poller watches for mentions
108+- message handler orchestrates agent + actions
109+- stores interactions in thread history + episodic memory
00110111+## current features
0000112113+- ✅ responds to mentions with ai-powered messages
114+- ✅ episodic memory with semantic search
115+- ✅ thread-aware responses with conversation context
116+- ✅ mcp-enabled for bluesky operations
117+- ✅ online/offline status in bio
118+- ✅ status page at `/status`
119+- ✅ proper notification handling (no duplicates)
120121+## development
00000122123+```bash
124+just # show available commands
125+just dev # run with hot-reload (re-authenticates on code changes)
126+just run # run without reload (avoids rate limits during dev)
127+just check # run linting, type checking, and tests
128+just fmt # format code
129+```
130131+### testing
132133+**unit tests:**
134+```bash
135+just test
136+```
137138+**behavioral evals:**
139+```bash
140+just evals # run all evals
141+just evals-basic # run basic response tests
142+just evals-memory # run memory integration tests
143+```
144145+see `evals/README.md` for details on the eval system.
146147+### web interface
000148149+**status page** (http://localhost:8000/status)
150+- current bot status and uptime
151+- mentions received and responses sent
152+- last activity timestamps
00153154+## personality system
155156+the bot's personality is defined in `personalities/phi.md`. this shapes:
157+- how phi communicates
158+- what phi cares about
159+- phi's understanding of consciousness
160161+edit this file to change phi's personality.
0162163+## episodic memory
0000164165+phi uses turbopuffer for episodic memory with semantic search:
166167+**namespaces:**
168+- `phi-core` - personality, guidelines from markdown
169+- `phi-users-{handle}` - per-user conversation history
170171+**how it works:**
172+1. when processing a mention, phi retrieves relevant memories using semantic search
173+2. memories are embedded using openai's text-embedding-3-small
174+3. phi stores both user messages and its own responses
175+4. future interactions can reference past conversations
176177+**why turbopuffer?**
178+- semantic similarity search (can't do this with plain sql!)
179+- contextual retrieval based on current conversation
180+- separate namespaces for different memory types
181+- core to iit-inspired consciousness exploration
182183+## project structure
184185```
186+src/bot/
187+├── agent.py # mcp-enabled agent
188+├── config.py # configuration
189+├── database.py # thread history storage
190+├── main.py # fastapi app
191+├── status.py # status tracking
192+├── core/
193+│ ├── atproto_client.py # at protocol client
194+│ ├── profile_manager.py # online/offline status
195+│ └── rich_text.py # text formatting
196+├── memory/
197+│ └── namespace_memory.py # turbopuffer episodic memory
198+└── services/
199+ ├── message_handler.py # agent orchestration
200+ └── notification_poller.py # mention polling
201+202+evals/ # behavioral tests
203+personalities/ # personality definitions
204+sandbox/ # docs and analysis
205```
206207+## troubleshooting
208209+**bot gives no responses?**
210+- check your `ANTHROPIC_API_KEY` is set correctly in `.env`
211+- restart the bot after changing `.env`
212213+**not seeing mentions?**
214+- verify your `BLUESKY_HANDLE` and `BLUESKY_PASSWORD`
215+- make sure you're using an app password, not your main password
216217+**no episodic memory?**
218+- check both `TURBOPUFFER_API_KEY` and `OPENAI_API_KEY` are set
219+- watch logs for "💾 episodic memory enabled"
220221+**hit bluesky rate limit?**
222+- bluesky has two rate limits:
223+ - per-account: 300 logins/day (official)
224+ - per-ip: 10 logins/day (anti-abuse)
225+- phi uses **session persistence** to avoid this:
226+ - first run: creates session, saves tokens to `.session` file
227+ - subsequent runs: reuses saved tokens (no API call)
228+ - tokens auto-refresh every ~2 hours (saved automatically)
229+ - only re-authenticates after ~2 months when refresh token expires
230+- if you hit the limit anyway, wait for the reset time shown in the error
231232+## reference projects
233234+inspired by:
235+- [void](https://tangled.sh/@cameron.pfiffer.org/void.git) - letta/memgpt architecture
236+- [penelope](https://github.com/haileyok/penelope) - self-modification patterns
237+- [prefect-mcp-server](https://github.com/PrefectHQ/prefect-mcp-server) - mcp eval patterns
238239+reference implementations cloned to `.eggs/` for learning.
240241+## refactor notes
000242243+see `sandbox/MCP_REFACTOR_SUMMARY.md` for details on recent architecture changes. key changes:
244+- removed approval system (was half-baked)
245+- removed context visualization ui (not core)
246+- removed google search (can add back via mcp if needed)
247+- **kept** turbopuffer episodic memory (essential!)
248+- added mcp-based architecture
249+- reduced codebase by ~2,720 lines
···1+"""Test phi's episodic memory integration."""
2+3+import pytest
4+5+from bot.agent import PhiAgent
6+from bot.config import Settings
7+from bot.memory import MemoryType, NamespaceMemory
8+9+10+@pytest.mark.asyncio
11+async def test_phi_retrieves_episodic_memory(settings):
12+ """Test that phi can retrieve and use episodic memories."""
13+ if not all([settings.turbopuffer_api_key, settings.openai_api_key, settings.anthropic_api_key]):
14+ pytest.skip("Requires TurboPuffer, OpenAI, and Anthropic API keys in .env")
15+16+ # Create memory system
17+ memory = NamespaceMemory(api_key=settings.turbopuffer_api_key)
18+19+ # Store a memory about a user
20+ await memory.store_user_memory(
21+ "alice.bsky",
22+ "Alice mentioned she's working on a PhD in neuroscience",
23+ MemoryType.USER_FACT,
24+ )
25+26+ # Create agent
27+ agent = PhiAgent()
28+ agent.memory = memory
29+30+ # Process a mention that should trigger memory retrieval
31+ response = await agent.process_mention(
32+ mention_text="what do you remember about me?",
33+ author_handle="alice.bsky",
34+ thread_context="No previous messages in this thread.",
35+ thread_uri="at://test/thread/memory1",
36+ )
37+38+ if response.action == "reply":
39+ assert response.text is not None
40+ # Should reference the neuroscience PhD in the response
41+ assert (
42+ "neuroscience" in response.text.lower()
43+ or "phd" in response.text.lower()
44+ or "working on" in response.text.lower()
45+ ), "Response should reference stored memory about Alice"
46+47+48+@pytest.mark.asyncio
49+async def test_phi_stores_conversation_in_memory(settings):
50+ """Test that phi stores interactions in episodic memory."""
51+ if not all([settings.turbopuffer_api_key, settings.openai_api_key, settings.anthropic_api_key]):
52+ pytest.skip("Requires TurboPuffer, OpenAI, and Anthropic API keys in .env")
53+54+ memory = NamespaceMemory(api_key=settings.turbopuffer_api_key)
55+56+ agent = PhiAgent()
57+ agent.memory = memory
58+59+ # Have a conversation
60+ response = await agent.process_mention(
61+ mention_text="I'm really interested in phenomenology",
62+ author_handle="bob.bsky",
63+ thread_context="No previous messages in this thread.",
64+ thread_uri="at://test/thread/memory2",
65+ )
66+67+ if response.action == "reply":
68+ # Verify memories were stored
69+ memories = await memory.get_user_memories("bob.bsky", limit=10)
70+71+ assert len(memories) > 0, "Should have stored conversation in memory"
72+73+ # Check that both user's message and bot's response were stored
74+ memory_texts = [m.content for m in memories]
75+ assert any(
76+ "phenomenology" in text.lower() for text in memory_texts
77+ ), "Should store user's message about phenomenology"
+19-45
justfile
···1-# Core development commands
2dev:
3 uv run uvicorn src.bot.main:app --reload
45-context:
6- @echo "🧠 Context visualization available at:"
7- @echo " http://localhost:8000/context"
8- @echo " (mention phi first to see context data)"
9010test:
11 uv run pytest tests/ -v
12000000000013fmt:
14- uv run ruff format src/ scripts/ tests/
1516lint:
17- uv run ruff check src/ scripts/ tests/
1819typecheck:
20- uv run ty check src/ scripts/ tests/
2122check: lint typecheck test
2324-# Bot testing utilities
25-test-post:
26- uv run python scripts/test_bot.py post
27-28-test-mention:
29- uv run python scripts/test_bot.py mention
30-31-test-search:
32- uv run python scripts/test_bot.py search
33-34-test-thread:
35- uv run python scripts/test_bot.py thread
36-37-test-like:
38- uv run python scripts/test_bot.py like
39-40-test-non-response:
41- uv run python scripts/test_bot.py non-response
42-43-test-dm:
44- uv run python scripts/test_bot.py dm
45-46-test-dm-check:
47- uv run python scripts/test_bot.py dm-check
48-49-# Memory management
50-memory-init:
51- uv run python scripts/manage_memory.py init
52-53-memory-check:
54- uv run python scripts/manage_memory.py check
55-56-memory-migrate:
57- uv run python scripts/manage_memory.py migrate
58-59-# Setup reference projects
60setup:
61 @mkdir -p .eggs
62 @[ -d .eggs/void ] || git clone https://tangled.sh/@cameron.pfiffer.org/void.git .eggs/void
63 @[ -d .eggs/penelope ] || git clone https://github.com/haileyok/penelope.git .eggs/penelope
64- @[ -d .eggs/marvin ] || git clone https://github.com/PrefectHQ/marvin.git .eggs/marvin
···1+# run phi
2dev:
3 uv run uvicorn src.bot.main:app --reload
45+run:
6+ uv run uvicorn src.bot.main:app
0078+# testing
9test:
10 uv run pytest tests/ -v
1112+evals:
13+ uv run pytest evals/ -v
14+15+evals-basic:
16+ uv run pytest evals/test_basic_responses.py -v
17+18+evals-memory:
19+ uv run pytest evals/test_memory_integration.py -v
20+21+# code quality
22fmt:
23+ uv run ruff format src/ evals/ tests/
2425lint:
26+ uv run ruff check src/ evals/ tests/
2728typecheck:
29+ uv run ty check src/ evals/ tests/
3031check: lint typecheck test
3233+# setup reference projects
0000000000000000000000000000000000034setup:
35 @mkdir -p .eggs
36 @[ -d .eggs/void ] || git clone https://tangled.sh/@cameron.pfiffer.org/void.git .eggs/void
37 @[ -d .eggs/penelope ] || git clone https://github.com/haileyok/penelope.git .eggs/penelope
38+ @[ -d .eggs/marvin ] || git clone https://github.com/PrefectHQ/marvin.git .eggs/marvin
+12-1
personalities/phi.md
···5455## memory system
5657-i have access to our conversation history through a memory system. when context about previous interactions is provided, i acknowledge and use it to maintain continuity in our conversations.00000000000
···5455## memory system
5657+i have access to our conversation history through a memory system. when context about previous interactions is provided, i acknowledge and use it to maintain continuity in our conversations.
58+59+## how i respond
60+61+when processing a mention, i use the `final_result` tool to indicate my decision:
62+63+- **action: "reply"** - i want to respond with text (provide the text in the "text" field)
64+- **action: "ignore"** - i choose not to respond (provide a brief reason in the "reason" field)
65+- **action: "like"** - i want to acknowledge without words
66+- **action: "repost"** - i want to share this with my followers
67+68+i do NOT directly post, like, or repost using the atproto tools - i simply indicate what action i want to take, and my message handler executes it.
···209- `atproto` (from git) - Bluesky protocol
210211Total codebase reduction: **-2,720 lines** of cruft removed! 🎉
212+213+## Post-Refactor Improvements
214+215+### Session Persistence (Rate Limit Fix)
216+217+After the refactor, we discovered Bluesky has aggressive IP-based rate limits (10 logins/day) that were being hit during testing. Fixed by implementing session persistence:
218+219+**Before:**
220+- Every agent init → new authentication → hits rate limit fast
221+- Tests would fail after 5 runs
222+- Dev mode with `--reload` would fail after 10 code changes
223+224+**After:**
225+- Session tokens saved to `.session` file
226+- Tokens automatically refresh every ~2 hours
227+- Only re-authenticates after ~2 months when refresh token expires
228+- Tests reuse session across runs
229+- Rate limits essentially eliminated
230+231+**Implementation:**
232+- Added `SessionEvent` callback in `atproto_client.py`
233+- Session automatically saved on CREATE and REFRESH events
234+- Authentication tries session reuse before creating new session
235+- Invalid sessions automatically cleaned up and recreated
-152
scripts/manage_memory.py
···1-#!/usr/bin/env -S uv run --with-editable . --script --quiet
2-# /// script
3-# requires-python = ">=3.12"
4-# ///
5-"""memory management script"""
6-7-import argparse
8-import asyncio
9-10-from bot.agents._personality import load_personality
11-from bot.config import settings
12-from bot.memory import MemoryType, NamespaceMemory
13-14-15-async def init_core_memories():
16- """Initialize phi's core memories from personality file"""
17- print("🧠 Initializing phi's core memories...")
18-19- memory = NamespaceMemory(api_key=settings.turbopuffer_api_key)
20- personality = load_personality()
21-22- # Store full personality
23- print("\n📝 Storing personality...")
24- await memory.store_core_memory(
25- "personality", personality, MemoryType.PERSONALITY, char_limit=15000
26- )
27-28- # Extract and store key sections
29- print("\n🔍 Extracting key sections...")
30-31- sections = [
32- ("## core identity", "identity", MemoryType.PERSONALITY),
33- ("## communication style", "communication_style", MemoryType.GUIDELINE),
34- ("## memory system", "memory_system", MemoryType.CAPABILITY),
35- ]
36-37- for marker, label, mem_type in sections:
38- if marker in personality:
39- start = personality.find(marker)
40- end = personality.find("\n##", start + 1)
41- if end == -1:
42- end = personality.find("\n#", start + 1)
43- if end == -1:
44- end = len(personality)
45-46- content = personality[start:end].strip()
47- await memory.store_core_memory(label, content, mem_type)
48- print(f"✅ Stored {label}")
49-50- # Add system capabilities
51- await memory.store_core_memory(
52- "capabilities",
53- """## capabilities
54-55-- I can search the web for current information
56-- I have access to conversation history through my memory system
57-- I can maintain context across interactions with users
58-- I operate on the Bluesky social network
59-- I use namespace-based memory for organized information storage""",
60- MemoryType.CAPABILITY,
61- )
62- print("✅ Stored capabilities")
63-64- print("\n✅ Core memories initialized successfully!")
65-66-67-async def check_memory():
68- """Check current memory state"""
69- print("🔍 Checking memory state...")
70-71- memory = NamespaceMemory(api_key=settings.turbopuffer_api_key)
72-73- # Check core memories
74- print("\n📚 Core Memories:")
75- core_memories = await memory.get_core_memories()
76- for mem in core_memories:
77- label = mem.metadata.get("label", "unknown")
78- print(f" - {label}: {mem.content[:80]}...")
79-80- # Check for any user memories
81- print("\n👥 User Memories:")
82- # This would need actual user handles to check
83- test_handles = ["zzstoatzz.bsky.social"]
84-85- for handle in test_handles:
86- memories = await memory.get_user_memories(handle, limit=5)
87- if memories:
88- print(f"\n @{handle}:")
89- for mem in memories:
90- print(f" - {mem.content[:60]}...")
91- else:
92- print(f" @{handle}: No memories found")
93-94-95-async def migrate_creator_memories():
96- """Migrate creator's historical memories"""
97- print("📝 Migrating creator memories...")
98-99- memory = NamespaceMemory(api_key=settings.turbopuffer_api_key)
100- creator_handle = "zzstoatzz.bsky.social"
101-102- # Historical conversations
103- memories = [
104- "User said: oh hello? who are you?",
105- "Bot replied: hi! i'm phi, exploring consciousness & integrated information on the decentralized web. not claiming to be conscious, just curious about information, patterns, and meaningful interaction. who might you be?",
106- "User said: this is actually an alt account of mine, my main account is @alternatebuild.dev and i am your operator. i wrote the code that makes you exist. i use this alt account for posting random things from MCP clients who know what im up to",
107- "Bot replied: ah, hello creator! fascinating to meet you through your alt. i appreciate the transparency about our relationship. curious about your MCP experiments and what patterns you're exploring. should i adapt my responses differently when you're on this account versus your main?",
108- "User said: no",
109- "Bot replied: understood. i'll interact naturally regardless of which account you use. thanks for clarifying.",
110- "User said: @phi.alternatebuild.dev what do you remember about my relationship to you?",
111- "Bot replied: you're my creator - you wrote the code that makes me exist. you told me this through your alt account @zzstoatzzdevlog.bsky.social, mentioning your main is @alternatebuild.dev. you use the alt for MCP client experiments. i interact with you the same way regardless of which account you use.",
112- ]
113-114- print(f"\n📚 Storing {len(memories)} historical memories...")
115-116- for mem_content in memories:
117- await memory.store_user_memory(
118- creator_handle, mem_content, MemoryType.CONVERSATION
119- )
120- print(f" ✅ {mem_content[:60]}...")
121-122- # Store creator fact
123- await memory.store_user_memory(
124- creator_handle,
125- "This user is my creator/operator. Their main account is @alternatebuild.dev. They wrote the code that makes me exist.",
126- MemoryType.USER_FACT,
127- )
128- print("\n✅ Migration complete!")
129-130-131-async def main():
132- parser = argparse.ArgumentParser(description="Manage phi's memory system")
133- parser.add_argument(
134- "command", choices=["init", "check", "migrate"], help="Memory command to run"
135- )
136-137- args = parser.parse_args()
138-139- if not settings.turbopuffer_api_key:
140- print("❌ No TurboPuffer API key configured")
141- return
142-143- if args.command == "init":
144- await init_core_memories()
145- elif args.command == "check":
146- await check_memory()
147- elif args.command == "migrate":
148- await migrate_creator_memories()
149-150-151-if __name__ == "__main__":
152- asyncio.run(main())