System Architecture
PiCrust is built with a clear separation of concerns, designed specifically for frontend-backend applications like Tauri desktop apps.Core Components
AgentRuntime
The AgentRuntime is the orchestrator. It:- Spawns agents as independent async tasks
- Maintains a registry of running agents by session ID
- Provides global permission rules shared across all agents
- Handles agent lifecycle (spawn, get, shutdown)
- Thread-safe (can be shared across threads)
- Single runtime can manage hundreds of agents
- Each agent runs independently
AgentHandle
The AgentHandle is your interface to a running agent. It:- Sends input to the agent
- Subscribes to output streams
- Sends permission responses
- Checks agent state
- Can interrupt or shutdown the agent
- Cloneable (can be shared across threads/tasks)
- Non-blocking operations
- Channel-based communication
StandardAgent
The StandardAgent is the brains. It:- Implements the main agent loop
- Manages conversation with the LLM
- Executes tools with permissions
- Streams output to subscribers
- Persists conversation history
- Stateful (maintains conversation context)
- Async-first architecture
- Extensible through hooks and context injection
AgentSession
The AgentSession handles persistence. It:- Stores conversation history on disk
- Maintains session metadata
- Supports parent-child relationships (for subagents)
- Provides conversation naming
- Write-through persistence (immediate disk writes)
- Stored in
./sessions/{session_id}/ - JSON format for portability
Communication Flow
Input Flow
Output Flow
Permission Flow
Data Flow
Dual-Channel Architecture
The SDK uses a dual-channel approach for conversation data: 1. Stream (Ephemeral)- Real-time output via broadcast channels
- Fast, in-memory
- Lost if no subscribers
- Perfect for live UIs
- Disk-based storage
- Durable, reliable
- Always available
- Ground truth for conversation state
Agent Lifecycle
States
State Transitions
Threading Model
Async Tasks
Each agent runs as an independenttokio::task:
Thread Safety
- AgentRuntime:
Arcwrapping for shared access - AgentHandle: Cloneable, uses channels for communication
- Tools: Must be
Send + Sync - Sessions: Write-through to disk, no shared state
Concurrent Access
Multiple threads can safely:- Send input to the same agent
- Subscribe to agent output
- Check agent state
- Access different agents simultaneously
Memory Model
What’s In-Memory
- Current conversation context (for LLM calls)
- Broadcast channel buffers (recent output chunks)
- Permission rules (session, local, global)
- Tool registry
- MCP connections
What’s On-Disk
- Complete conversation history (
./sessions/{id}/history.json) - Session metadata (
./sessions/{id}/metadata.json) - Debug logs (if enabled,
./sessions/{id}/debugger/)
Memory Efficiency
- Prompt caching reduces redundant LLM processing
- Sessions are loaded on-demand
- History is only read when needed
- Broadcast channels have bounded buffers
Extensibility Points
1. Custom Tools
Implement theTool trait:
2. Hooks
Intercept agent behavior:3. Context Injection
Add dynamic context to LLM calls:4. Custom LLM Providers
Implement theLlmProvider trait:
5. MCP Servers
Connect external tool providers:Design Principles
1. Frontend-First
The architecture prioritizes responsive UIs:- Streaming output for real-time feedback
- Non-blocking permission requests
- State visibility for UI updates
2. Type Safety
Rust’s type system prevents entire classes of errors:- Compile-time verification
- No null pointer exceptions
- Memory safety guarantees
3. Production-Ready
Built for real applications:- Session persistence (survive crashes)
- Permission system (security)
- Error handling (graceful degradation)
- Debugger (troubleshooting)
4. Flexibility
Easy to customize and extend:- Pluggable LLM providers
- Custom tools
- Hook system
- Context injection
5. Performance
Optimized for efficiency:- Async I/O (non-blocking)
- Prompt caching (90% cost reduction)
- Connection pooling
- Minimal allocations
Comparison with Other Architectures
vs. Stateless Request/Response
PiCrust:- Maintains conversation state
- Session persistence
- Multi-turn interactions
- No state between requests
- Must send full history each time
- Simpler but less capable
vs. Monolithic Agent
PiCrust:- Multiple independent agents
- Subagent spawning
- Runtime management
- Single agent instance
- No isolation
- Harder to scale
vs. Microservices
PiCrust:- Embedded in your application
- Type-safe communication
- No network overhead
- Separate services
- Network communication
- More operational complexity
Next Steps
Now that you understand the architecture:Runtime & Lifecycle
Deep dive into AgentRuntime and agent lifecycle
Sessions & Persistence
Learn about conversation persistence
Message Flow
Understand input/output communication
Agent States
Explore all agent states and transitions