| Crates.io | systemprompt-traits |
| lib.rs | systemprompt-traits |
| version | 0.0.11 |
| created_at | 2026-01-21 17:12:39.147803+00 |
| updated_at | 2026-01-25 21:41:27.135632+00 |
| description | Minimal shared traits and contracts for systemprompt.io |
| homepage | https://systemprompt.io |
| repository | https://github.com/systempromptio/systemprompt-core |
| max_upload_size | |
| id | 2059716 |
| size | 125,869 |
Minimal shared traits and contracts for systemprompt.io.
Part of the Shared layer in the systemprompt.io architecture.
This crate provides the core trait definitions that enable polymorphism, dependency injection, and consistent patterns across the systemprompt.io codebase.
Add to your Cargo.toml:
[dependencies]
systemprompt-traits = "0.0.1"
| Feature | Default | Description |
|---|---|---|
web |
No | Axum router types for ApiModule trait |
Repository - Base trait for all repository implementations
use systemprompt_traits::{Repository, RepositoryError};
impl Repository for MyRepository {
type Pool = DbPool;
type Error = RepositoryError;
fn pool(&self) -> &Self::Pool {
&self.db_pool
}
}
CrudRepository<T> - Generic CRUD operations trait
use systemprompt_traits::CrudRepository;
impl CrudRepository<User> for UserRepository {
type Id = String;
async fn create(&self, entity: User) -> Result<User, Self::Error> { ... }
async fn get(&self, id: Self::Id) -> Result<Option<User>, Self::Error> { ... }
async fn update(&self, entity: User) -> Result<User, Self::Error> { ... }
async fn delete(&self, id: Self::Id) -> Result<(), Self::Error> { ... }
async fn list(&self) -> Result<Vec<User>, Self::Error> { ... }
}
RepositoryError - Standard error type for repository operations
pub enum RepositoryError {
DatabaseError(sqlx::Error),
NotFound(String),
SerializationError(serde_json::Error),
InvalidData(String),
ConstraintViolation(String),
GenericError(anyhow::Error),
}
AppContext - Application context trait for dependency injection
use systemprompt_traits::AppContext;
impl AppContext for MyAppContext {
fn config(&self) -> Arc<dyn ConfigProvider> { ... }
fn module_registry(&self) -> Arc<dyn ModuleRegistry> { ... }
fn database_handle(&self) -> Arc<dyn DatabaseHandle> { ... }
}
ConfigProvider - Configuration provider trait
impl ConfigProvider for Config {
fn get(&self, key: &str) -> Option<String> { ... }
fn database_url(&self) -> &str { ... }
fn system_path(&self) -> &str { ... }
fn jwt_secret(&self) -> &str { ... }
fn api_port(&self) -> u16 { ... }
}
ModuleRegistry - Module registry trait for dynamic module management
impl ModuleRegistry for MyModuleRegistry {
fn get_module(&self, name: &str) -> Option<Arc<dyn Module>> { ... }
fn list_modules(&self) -> Vec<String> { ... }
}
Service - Base service trait with lifecycle methods
use systemprompt_traits::Service;
#[async_trait]
impl Service for MyService {
fn name(&self) -> &str { "my-service" }
async fn start(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ... }
async fn stop(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ... }
async fn health_check(&self) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> { ... }
}
AsyncService - Async service trait for long-running background tasks
use systemprompt_traits::AsyncService;
#[async_trait]
impl AsyncService for MyAsyncService {
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Long-running task
}
}
Module - Core module trait for systemprompt.io modules
#[async_trait]
impl Module for MyModule {
fn name(&self) -> &str { "my-module" }
fn version(&self) -> &str { "1.0.0" }
fn display_name(&self) -> &str { "My Module" }
async fn initialize(&self) -> Result<(), Box<dyn std::error::Error>> { ... }
}
ApiModule - Module trait with REST API support
#[async_trait]
impl ApiModule for MyApiModule {
fn router(&self, ctx: Arc<dyn AppContext>) -> axum::Router { ... }
}
Use Traits When:
Use Concrete Types When:
Traits enable easy mocking:
#[cfg(test)]
mod tests {
use super::*;
struct MockRepository {
pool: MockPool,
}
impl Repository for MockRepository {
type Pool = MockPool;
type Error = RepositoryError;
fn pool(&self) -> &Self::Pool { &self.pool }
}
#[tokio::test]
async fn test_with_mock() {
let repo = MockRepository { pool: MockPool::new() };
// Test using trait methods
}
}
All repository errors automatically convert to ApiError:
use systemprompt_models::{ApiError, RepositoryError};
let result: Result<User, RepositoryError> = repo.get_user("id").await;
let api_result: Result<User, ApiError> = result.map_err(|e| e.into());
This crate follows the Interface Segregation Principle from SOLID:
Minimal dependencies to avoid circular deps:
async-trait - Async trait supportanyhow - Error handlingaxum - Router type for ApiModuleinventory - Module registrationthiserror - Error derive macrossqlx - Database types for Repositoryserde_json - Serialization errorsNo dependencies on other systemprompt.io crates - this is intentional to prevent circular dependencies.
ToolProvider - Abstract tool discovery and executionEnables modules to use tools without depending on specific implementations (e.g., MCP).
use systemprompt_traits::{ToolProvider, ToolContext, ToolDefinition};
#[async_trait]
impl ToolProvider for MyToolProvider {
async fn list_tools(&self, agent_name: &str, context: &ToolContext)
-> ToolProviderResult<Vec<ToolDefinition>> { ... }
async fn call_tool(&self, request: &ToolCallRequest, service_id: &str, context: &ToolContext)
-> ToolProviderResult<ToolCallResult> { ... }
async fn refresh_connections(&self, agent_name: &str) -> ToolProviderResult<()> { ... }
async fn health_check(&self) -> ToolProviderResult<HashMap<String, bool>> { ... }
}
Supporting types: ToolDefinition, ToolCallRequest, ToolCallResult, ToolContent, ToolContext, ToolProviderError
LlmProvider - Abstract LLM interactionsuse systemprompt_traits::{LlmProvider, ChatRequest, ChatResponse};
#[async_trait]
impl LlmProvider for MyProvider {
async fn chat(&self, request: &ChatRequest) -> LlmProviderResult<ChatResponse> { ... }
async fn stream_chat(&self, request: &ChatRequest) -> LlmProviderResult<ChatStream> { ... }
fn default_model(&self) -> &str { "model-name" }
fn supports_model(&self, model: &str) -> bool { ... }
fn supports_streaming(&self) -> bool { true }
fn supports_tools(&self) -> bool { true }
}
ToolExecutor - Execute tools during conversationsuse systemprompt_traits::{ToolExecutor, ToolExecutionContext};
#[async_trait]
impl ToolExecutor for MyExecutor {
async fn execute(&self, tool_calls: Vec<ToolCallRequest>, tools: &[ToolDefinition],
context: &ToolExecutionContext) -> (Vec<ToolCallRequest>, Vec<ToolCallResult>) { ... }
}
Supporting types: ChatMessage, ChatRole, ChatRequest, ChatResponse, SamplingParameters, TokenUsage, ToolExecutionContext
FSL-1.1-ALv2 - See LICENSE for details.