Extending Perspt¶
How to add new capabilities to Perspt.
Adding a New CLI Command¶
Create command file:
crates/perspt-cli/src/commands/mycommand.rsuse anyhow::Result; pub async fn run(arg: String) -> Result<()> { println!("Running mycommand with: {}", arg); Ok(()) }
Register in mod.rs:
crates/perspt-cli/src/commands/mod.rspub mod mycommand;
Add to CLI enum:
crates/perspt-cli/src/main.rs#[derive(Subcommand)] enum Commands { // ... existing commands /// My new command Mycommand { /// Argument arg: String, }, }
Add match arm:
Some(Commands::Mycommand { arg }) => commands::mycommand::run(arg).await,
Adding a New Agent Tool¶
Define tool in tools.rs:
crates/perspt-agent/src/tools.rspub fn available_tools() -> Vec<ToolDefinition> { vec![ // ... existing tools ToolDefinition { name: "my_tool".to_string(), description: "Does something useful".to_string(), parameters: json!({ "type": "object", "properties": { "input": { "type": "string", "description": "The input" } }, "required": ["input"] }), }, ] }
Implement execution:
pub async fn execute(&self, call: &ToolCall) -> Result<ToolResult> { match call.name.as_str() { // ... existing tools "my_tool" => { let input = call.arguments["input"].as_str().unwrap(); Ok(ToolResult::Success(format!("Processed: {}", input))) } _ => Err(anyhow!("Unknown tool: {}", call.name)), } }
Adding a Custom Provider¶
The genai crate handles providers. To add custom support:
Set environment variable for new provider
Use provider-specific model names
For custom API endpoints, modify perspt-core/src/llm_provider.rs.
Adding TUI Components¶
Create widget in perspt-tui:
crates/perspt-tui/src/my_widget.rsuse ratatui::{prelude::*, widgets::*}; pub struct MyWidget { data: String, } impl MyWidget { pub fn new(data: String) -> Self { Self { data } } pub fn render(&self, frame: &mut Frame, area: Rect) { let block = Block::default().title("My Widget").borders(Borders::ALL); let paragraph = Paragraph::new(self.data.clone()).block(block); frame.render_widget(paragraph, area); } }
Register in lib.rs:
pub mod my_widget; pub use my_widget::MyWidget;
Adding Policy Rules¶
Extend the Starlark policy engine in crates/perspt-policy/src/engine.rs:
pub fn add_custom_rule(&mut self, pattern: &str, action: Action) {
self.rules.push(Rule {
pattern: pattern.to_string(),
action,
reason: None,
});
}
Testing Extensions¶
# Test specific crate
cargo test -p perspt-agent
# Run all tests
cargo test --all
# With coverage
cargo tarpaulin
Documentation¶
Update docs when extending:
Update API docs in
docs/perspt_book/source/api/Add usage examples to relevant tutorials
Rebuild:
cd docs/perspt_book && make html
See Also¶
Architecture - Crate design
Testing - Testing guide
API Reference - API reference