ArchitectureΒΆ
Perspt is built as a modern, modular Rust application using a 7-crate workspace architecture. This design enables clean separation of concerns, independent testing, and easy extensibility.
Workspace OverviewΒΆ
![digraph workspace {
rankdir=TB;
node [shape=folder, style=filled, fontname="Helvetica"];
subgraph cluster_workspace {
label="perspt/crates/";
style=dashed;
color=gray;
cli [label="perspt-cli\n(CLI Entry)", fillcolor="#4ECDC4"];
core [label="perspt-core\n(LLM, Config)", fillcolor="#45B7D1"];
tui [label="perspt-tui\n(Terminal UI)", fillcolor="#96CEB4"];
agent [label="perspt-agent\n(SRBN Engine)", fillcolor="#FFEAA7"];
policy [label="perspt-policy\n(Security)", fillcolor="#DDA0DD"];
sandbox [label="perspt-sandbox\n(Isolation)", fillcolor="#F8B739"];
store [label="perspt-store\n(Persistence)", fillcolor="#87CEEB"];
}
}](../_images/graphviz-a4d5310a2398e07c8a81a94f224bb835fe5dec4c.png)
Perspt Workspace StructureΒΆ
Crate Dependency GraphΒΆ
![digraph dependencies {
rankdir=TB;
node [shape=box, style="rounded,filled", fontname="Helvetica", fontsize=11];
edge [color="#666666"];
cli [label="perspt-cli\nβββββββββββ\n10 Subcommands", fillcolor="#4ECDC4"];
subgraph cluster_middle {
rank=same;
style=invis;
tui [label="perspt-tui\nβββββββββββ\nAgent UI\nDashboard\nDiff Viewer", fillcolor="#96CEB4"];
agent [label="perspt-agent\nβββββββββββ\nOrchestrator\nLSP Client\nTools", fillcolor="#FFEAA7"];
core [label="perspt-core\nβββββββββββ\nGenAIProvider\nConfig\nMemory", fillcolor="#45B7D1"];
}
subgraph cluster_bottom {
rank=same;
style=invis;
policy [label="perspt-policy\nβββββββββββ\nPolicyEngine\nSanitizer", fillcolor="#DDA0DD"];
sandbox [label="perspt-sandbox\nβββββββββββ\nSandboxedCommand", fillcolor="#F8B739"];
store [label="perspt-store\nβββββββββββ\nSQLite DB\nMerkle Tree", fillcolor="#87CEEB"];
}
cli -> tui;
cli -> agent;
cli -> core;
cli -> store;
agent -> policy;
agent -> sandbox;
agent -> core;
agent -> store;
}](../_images/graphviz-58a5fcc69fca906229265ed331bcb36b454a98e2.png)
Crate DependenciesΒΆ
SRBN Control FlowΒΆ
![digraph srbn {
rankdir=LR;
node [shape=box, style="rounded,filled", fontname="Helvetica"];
edge [fontname="Helvetica", fontsize=10];
start [shape=circle, label="", fillcolor="#333333", width=0.3];
sheaf [label="1. Sheafification\nββββββββββββββ\nTask β TaskPlan\n(Architect)", fillcolor="#E8F5E9"];
spec [label="2. Speculation\nββββββββββββββ\nGenerate Code\n(Actuator)", fillcolor="#E3F2FD"];
verify [label="3. Verification\nββββββββββββββ\nCompute V(x)\n(LSP + Tests)", fillcolor="#FFF3E0"];
converge [shape=diamond, label="V(x) > Ξ΅?", fillcolor="#FFECB3"];
commit [label="5. Commit\nββββββββββββββ\nMerkle Ledger\n(Record)", fillcolor="#F3E5F5"];
end [shape=doublecircle, label="", fillcolor="#333333", width=0.3];
start -> sheaf;
sheaf -> spec;
spec -> verify;
verify -> converge;
converge -> spec [label="Yes\n(retry)", style=dashed, color="#E53935"];
converge -> commit [label="No\n(stable)"];
commit -> end;
}](../_images/graphviz-5dce0ee919ead095ea46e8d394a33290ef14ed7e.png)
Stabilized Recursive Barrier NetworkΒΆ
Crate DetailsΒΆ
perspt-cliΒΆ
The command-line interface providing 10 subcommands:
Command |
Purpose |
Key Options |
|---|---|---|
|
Interactive TUI |
|
|
SRBN autonomous coding |
--architect-model, --actuator-model--energy-weights, --mode |
|
Project setup |
|
|
Configuration |
|
|
Merkle ledger |
|
|
Agent status |
(none) |
|
Cancel session |
|
|
Resume session |
|
|
View LLM logs |
|
|
CLI chat mode |
|
Source: crates/perspt-cli/src/
perspt-coreΒΆ
Thread-safe LLM provider and configuration:
/// Thread-safe LLM provider using Arc<RwLock>.
/// Can be safely cloned and shared across async tasks.
#[derive(Clone)]
pub struct GenAIProvider {
client: Arc<Client>,
shared: Arc<RwLock<SharedState>>,
}
impl GenAIProvider {
pub fn new() -> Result<Self>
pub fn new_with_config(provider: Option<&str>, api_key: Option<&str>) -> Result<Self>
pub async fn generate_response_stream_to_channel(...) -> Result<()>
pub async fn get_total_tokens_used(&self) -> usize
}
Modules:
- config.rs:
Simple Config struct (provider, model, api_key)
- llm_provider.rs:
GenAIProvider with streaming support
- memory.rs:
Conversation memory management
Source: crates/perspt-core/src/
perspt-agentΒΆ
The Stabilized Recursive Barrier Network implementation.
Energy Computation
Default weights: Ξ±=1.0, Ξ²=0.5, Ξ³=2.0
Key Modules:
Module |
Size |
Description |
|---|---|---|
|
34KB |
SRBN control loop, model tiers, retry policy |
|
28KB |
LSP client for Python ( |
|
12KB |
Agent tools (search, read, write, shell) |
|
24KB |
TaskPlan, Node, Energy, ToolCall types |
|
6KB |
Merkle ledger for change tracking |
|
15KB |
pytest integration, V_log calculation |
|
10KB |
Code context extraction |
Source: crates/perspt-agent/src/
perspt-tuiΒΆ
Ratatui-based terminal interface components:
- agent_app.rs:
Main agent mode TUI application
- dashboard.rs:
Status dashboard with metrics
- diff_viewer.rs:
Side-by-side file diff display
- review_modal.rs:
Change approval/rejection UI
- task_tree.rs:
Hierarchical task visualization
Source: crates/perspt-tui/src/
perspt-policyΒΆ
Starlark-based policy engine for command approval:
pub struct PolicyEngine {
// Evaluates Starlark rules for command safety
}
pub struct Sanitizer {
// Cleans and validates shell commands
// Prevents path traversal, injection attacks
}
Source: crates/perspt-policy/src/
perspt-sandboxΒΆ
Safe command execution with process isolation.
Source: crates/perspt-sandbox/src/
perspt-storeΒΆ
DuckDB-based persistence layer for session management and LLM logging:
pub struct SessionStore {
conn: Connection,
}
impl SessionStore {
pub fn new(db_path: &Path) -> Result<Self>
pub fn create_session(task: &str, workspace: &str) -> Result<String>
pub fn record_llm_request(...) -> Result<()>
pub fn get_llm_requests(session_id: &str) -> Result<Vec<LlmRequestRecord>>
}
Key Types:
SessionRecordβ Session metadata (id, task, status, timestamps)LlmRequestRecordβ LLM request/response with latency and tokensEnergyRecordβ Energy history for stability trackingNodeStateRecordβ SRBN node state snapshots
Source: crates/perspt-store/src/
Design PrinciplesΒΆ
Each crate has a single responsibility:
perspt-cli knows CLI, not LLM internals
perspt-core provides LLM abstraction, not UI
perspt-agent implements SRBN, delegates UI
GenAIProvider uses Arc<RwLock<SharedState>> for:
Safe cloning across async tasks
Shared token counting and rate limiting
Concurrent access from orchestrator and UI
All crates use anyhow::Result for:
Contextual error messages
Error propagation with backtrace
User-friendly error display
Built on Tokio runtime with:
Streaming LLM responses via channels
Non-blocking UI updates
Concurrent tool execution
Configuration SourcesΒΆ
Priority |
Source |
Example |
|---|---|---|
1 |
CLI Arguments |
|
2 |
Environment Variables |
|
3 |
Config File |
|
4 |
Built-in Defaults |
provider: openai, model: gpt-4 |
Supported ProvidersΒΆ
Provider |
Environment Variable |
Models |
|---|---|---|
OpenAI |
|
GPT-5.2, o3-mini, o1-preview |
Anthropic |
|
Claude Opus 4.5 |
|
Gemini 3 Flash/Pro |
|
Groq |
|
Llama 3.x |
Ollama |
(none) |
Local models |
Extension PointsΒΆ
Adding a New CommandΒΆ
Create
crates/perspt-cli/src/commands/mycommand.rsAdd variant to
Commandsenum inmain.rsAdd match arm in
main()
Adding a New ToolΒΆ
Add tool definition to
crates/perspt-agent/src/tools.rsRegister in
AgentTools::available_tools()Implement execution in
execute_tool()
Adding a ProviderΒΆ
The genai crate handles providers. To customize:
Set appropriate environment variable
Use provider-specific model names
See also
API Reference - Per-crate API reference
Contributing - How to contribute
Testing - Testing guide