a digital entity named phi that roams bsky
architecture#
phi is a notification-driven agent that responds to mentions on bluesky.
data flow#
notification arrives
↓
fetch thread context from network (ATProto)
↓
retrieve relevant memories (TurboPuffer)
↓
agent decides action (PydanticAI + Claude)
↓
execute via MCP tools (post/like/repost)
key components#
notification poller#
- checks for mentions every 10s
- tracks processed URIs to avoid duplicates
- runs in background thread
message handler#
- orchestrates the response flow
- fetches thread context from ATProto network
- passes context to agent
- executes agent's chosen action
phi agent#
- loads personality from
personalities/phi.md - builds context from thread + episodic memory
- returns structured response:
Response(action, text, reason) - has access to MCP tools via stdio
atproto client#
- session persistence (saves to
.session) - auto-refresh tokens every ~2h
- provides bluesky operations
why this design#
network-first thread context: fetch threads from ATProto instead of caching in sqlite. network is source of truth, no staleness issues.
episodic memory for semantics: turbopuffer stores embeddings for semantic search across all conversations. different purpose than thread chronology.
mcp for extensibility: tools provided by external server via stdio. easy to add new capabilities without changing agent code.
structured outputs: agent returns typed Response objects, not free text. clear contract between agent and handler.