Crate Reference

📦 Detailed documentation of all PiSovereign crates

This document provides comprehensive documentation for each crate in the PiSovereign workspace.

Table of Contents


Overview

PiSovereign consists of 12 crates organized by architectural layer:

LayerCratesPurpose
DomaindomainCore business logic, entities, value objects
ApplicationapplicationUse cases, services, port definitions
InfrastructureinfrastructureDatabase, cache, secrets, telemetry
AIai_core, ai_speechInference engine, speech processing
Integrationintegration_*External service adapters
Presentationpresentation_*HTTP API, CLI

Domain Layer

domain

Purpose: Contains the core business logic with zero external dependencies (except std). Defines the ubiquitous language of the application.

Dependencies: None (pure Rust)

Entities

EntityDescription
UserRepresents a system user with profile information
ConversationA chat conversation containing messages
MessageA single message in a conversation
ApprovalRequestPending approval for sensitive operations
AuditEntryAudit log entry for compliance
CalendarEventCalendar event representation
EmailMessageEmail representation
WeatherDataWeather information
// Example: Conversation entity
pub struct Conversation {
    pub id: ConversationId,
    pub title: Option<String>,
    pub system_prompt: Option<String>,
    pub messages: Vec<Message>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

Value Objects

Value ObjectDescription
UserIdUnique user identifier (UUID)
ConversationIdUnique conversation identifier
MessageContentValidated message content
TenantIdMulti-tenant identifier
PhoneNumberValidated phone number
// Example: UserId value object
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UserId(Uuid);

impl UserId {
    pub fn new() -> Self {
        Self(Uuid::new_v4())
    }
    
    pub fn from_uuid(uuid: Uuid) -> Self {
        Self(uuid)
    }
}

Commands

CommandDescription
UserCommandCommands from users (Briefing, Ask, Help, etc.)
SystemCommandInternal system commands
// User command variants
pub enum UserCommand {
    MorningBriefing,
    CreateCalendarEvent { title: String, start: DateTime<Utc>, end: DateTime<Utc> },
    SummarizeInbox { count: usize },
    DraftEmail { to: String, subject: String },
    SendEmail { draft_id: String },
    Ask { query: String },
    Echo { message: String },
    Help,
}

Domain Errors

#[derive(Debug, thiserror::Error)]
pub enum DomainError {
    #[error("Invalid message content: {0}")]
    InvalidContent(String),
    
    #[error("Conversation not found: {0}")]
    ConversationNotFound(ConversationId),
    
    #[error("User not authorized: {0}")]
    Unauthorized(String),
}

Application Layer

application

Purpose: Orchestrates use cases by coordinating domain entities and infrastructure through port interfaces.

Dependencies: domain

Services

ServiceDescription
AgentServiceIntent routing pipeline (conversational filter → quick patterns → workflow detection → LLM intent)
ChatServiceLLM chat with RAG context injection and automatic memory storage
ConversationServiceManages conversations and messages
VoiceMessageServiceSTT → LLM → TTS pipeline
CommandServiceParses and executes user commands
MemoryServiceMemory storage, semantic search, encryption, decay, and deduplication
ApprovalServiceHandles approval workflows
BriefingServiceGenerates morning briefings
CalendarServiceCalendar operations
EmailServiceEmail operations
HealthServiceSystem health checks

Command Parser Modules

ModuleDescription
conversational_filterZero-LLM-cost regex filter for greetings, introductions, and small talk
llmLLM-based intent parsing with confidence scoring and keyword post-validation
workflow_parserMulti-step workflow detection with hardened negative examples
// Example: ConversationService
pub struct ConversationService<R, I>
where
    R: ConversationRepository,
    I: InferencePort,
{
    repository: Arc<R>,
    inference: Arc<I>,
}

impl<R, I> ConversationService<R, I>
where
    R: ConversationRepository,
    I: InferencePort,
{
    pub async fn send_message(
        &self,
        conversation_id: Option<ConversationId>,
        content: String,
    ) -> Result<Message, ServiceError> {
        // 1. Load or create conversation
        // 2. Build prompt with context
        // 3. Call inference engine
        // 4. Save and return response
    }
}

Ports (Trait Definitions)

PortDescription
InferencePortLLM inference operations
ConversationRepositoryConversation persistence
MemoryPortMemory persistence (store, search, decay)
MemoryContextPortRAG context injection into prompts
EmbeddingPortEmbedding vector generation
EncryptionPortContent encryption/decryption
SecretStoreSecret management
CachePortCaching abstraction
CalendarPortCalendar operations
EmailPortEmail operations
WeatherPortWeather data
SpeechPortSTT/TTS operations
WhatsAppPortWhatsApp messaging
ApprovalRepositoryApproval persistence
AuditRepositoryAudit logging
// Example: InferencePort
#[async_trait]
pub trait InferencePort: Send + Sync {
    async fn generate(
        &self,
        prompt: &str,
        options: InferenceOptions,
    ) -> Result<InferenceResponse, InferenceError>;
    
    async fn generate_stream(
        &self,
        prompt: &str,
        options: InferenceOptions,
    ) -> Result<Pin<Box<dyn Stream<Item = Result<String, InferenceError>> + Send>>, InferenceError>;
    
    async fn health_check(&self) -> Result<bool, InferenceError>;
    
    fn default_model(&self) -> &str;
}

Infrastructure Layer

infrastructure

Purpose: Provides concrete implementations of application ports for external systems.

Dependencies: domain, application

Adapters

AdapterImplementsDescription
VaultSecretStoreSecretStoreHashiCorp Vault KV v2
EnvironmentSecretStoreSecretStoreEnvironment variables
ChainedSecretStoreSecretStoreMulti-backend fallback
Argon2PasswordHasherPasswordHasherSecure password hashing
// Example: VaultSecretStore usage
let vault = VaultSecretStore::new(VaultConfig {
    address: "http://127.0.0.1:8200".to_string(),
    role_id: Some("...".to_string()),
    secret_id: Some("...".to_string()),
    mount_path: "secret".to_string(),
    ..Default::default()
})?;

let secret = vault.get_secret("pisovereign/whatsapp/access_token").await?;

Cache

ComponentDescription
MokaCacheL1 in-memory cache (fast, volatile)
RedbCacheL2 persistent cache (survives restarts)
TieredCacheCombines L1 + L2 with fallback
// TieredCache usage
let cache = TieredCache::new(
    MokaCache::new(10_000),  // 10k entries max
    RedbCache::new("/var/lib/pisovereign/cache.redb")?,
);

// Write-through to both layers
cache.set("key", "value", Duration::from_secs(3600)).await?;

// Read checks L1 first, then L2
let value = cache.get("key").await?;

Persistence

ComponentDescription
PgConversationRepositoryConversation storage
PgApprovalRepositoryApproval request storage
PgAuditRepositoryAudit log storage
PgUserRepositoryUser profile storage

Other Components

ComponentDescription
TelemetrySetupOpenTelemetry initialization
CronSchedulerCron-based task scheduling
TeraTemplatesTemplate rendering
RetryExecutorExponential backoff retry
SecurityValidatorConfig validation
ModelRoutingAdapterAdaptive 4-tier model routing (replaces ai_core::ModelSelector)
RuleBasedClassifierRule-based complexity classification
TemplateResponderInstant template responses for trivial queries
ModelRoutingMetricsAtomic counters for routing observability

AI Crates

ai_core

Purpose: Inference engine abstraction and Hailo-Ollama client.

Dependencies: domain, application

Components

ComponentDescription
HailoClientHailo-Ollama HTTP client
ModelSelectorDynamic model routing (Deprecated — use infrastructure::ModelRoutingAdapter)
// HailoClient usage
let client = HailoClient::new(InferenceConfig {
    base_url: "http://localhost:11434".to_string(),
    default_model: "gemma3:12b".to_string(),
    timeout_ms: 60000,
    ..Default::default()
})?;

let response = client.generate(
    "What is the capital of France?",
    InferenceOptions::default(),
).await?;

ai_speech

Purpose: Speech-to-Text and Text-to-Speech processing.

Dependencies: domain, application

Providers

ProviderDescription
HybridSpeechProviderLocal first, cloud fallback
LocalSttProviderwhisper.cpp integration
LocalTtsProviderPiper integration
OpenAiSpeechProviderOpenAI Whisper & TTS
// HybridSpeechProvider usage
let speech = HybridSpeechProvider::new(SpeechConfig {
    provider: SpeechProviderType::Hybrid,
    prefer_local: true,
    allow_cloud_fallback: true,
    ..Default::default()
})?;

// Transcribe audio
let text = speech.transcribe(&audio_data, "en").await?;

// Synthesize speech
let audio = speech.synthesize("Hello, world!", "en").await?;

Audio Conversion

ComponentDescription
AudioConverterFFmpeg-based format conversion

Supported formats: OGG/Opus, MP3, WAV, FLAC, M4A, WebM


Integration Crates

integration_whatsapp

Purpose: WhatsApp Business API integration.

Dependencies: domain, application

Components

ComponentDescription
WhatsAppClientMeta Graph API client
WebhookHandlerIncoming message handler
SignatureValidatorHMAC-SHA256 verification
// WhatsAppClient usage
let whatsapp = WhatsAppClient::new(WhatsAppConfig {
    access_token: "...".to_string(),
    phone_number_id: "...".to_string(),
    api_version: "v18.0".to_string(),
})?;

// Send text message
whatsapp.send_text("+1234567890", "Hello!").await?;

// Send audio message
whatsapp.send_audio("+1234567890", &audio_data).await?;

integration_email

Purpose: Generic email integration via IMAP/SMTP, supporting any provider (Gmail, Outlook, Proton Mail, and custom servers).

Dependencies: domain, application

Components

ComponentDescription
ImapClientEmail reading via IMAP
SmtpClientEmail sending via SMTP
EmailProviderConfigProvider-agnostic configuration
AuthMethodPassword or OAuth2 (XOAUTH2) authentication
ProviderPresetPre-configured settings for Proton, Gmail, Outlook
ReconnectingClientConnection resilience with auto-reconnect
use integration_email::{EmailProviderConfig, AuthMethod, ProviderPreset};

// Proton Mail via Bridge
let proton = EmailProviderConfig::with_credentials("user@proton.me", "bridge-password")
    .with_imap("127.0.0.1", 1143)
    .with_smtp("127.0.0.1", 1025);

// Gmail with OAuth2
let gmail = EmailProviderConfig::with_oauth2("user@gmail.com", "ya29.access-token")
    .with_preset(ProviderPreset::Gmail);

// Outlook with app password
let outlook = EmailProviderConfig::with_credentials("user@outlook.com", "app-password")
    .with_preset(ProviderPreset::Outlook);

integration_caldav

Purpose: CalDAV calendar integration.

Dependencies: domain, application

Components

ComponentDescription
CalDavClientCalDAV protocol client
ICalParseriCalendar parsing
// CalDavClient usage
let calendar = CalDavClient::new(CalDavConfig {
    server_url: "https://cal.example.com/dav.php".to_string(),
    username: "user".to_string(),
    password: "pass".to_string(),
    calendar_path: "/calendars/user/default/".to_string(),
})?;

// Fetch events
let events = calendar.get_events(start_date, end_date).await?;

// Create event
calendar.create_event(CalendarEvent {
    title: "Meeting".to_string(),
    start: start_time,
    end: end_time,
    ..Default::default()
}).await?;

integration_weather

Purpose: Open-Meteo weather API integration.

Dependencies: domain, application

Components

ComponentDescription
OpenMeteoClientWeather API client
// OpenMeteoClient usage
let weather = OpenMeteoClient::new(WeatherConfig {
    base_url: "https://api.open-meteo.com/v1".to_string(),
    forecast_days: 7,
    cache_ttl_minutes: 30,
})?;

// Get current weather
let current = weather.get_current(52.52, 13.405).await?;

// Get forecast
let forecast = weather.get_forecast(52.52, 13.405).await?;

Presentation Crates

presentation_http

Purpose: HTTP REST API using Axum.

Dependencies: All crates (orchestration layer)

Handlers

HandlerEndpointDescription
healthGET /healthLiveness probe
readyGET /readyReadiness with inference status
chatPOST /v1/chatSend chat message
chat_streamPOST /v1/chat/streamStreaming chat (SSE)
commandsPOST /v1/commandsExecute command
webhooksPOST /v1/webhooks/whatsappWhatsApp webhook
metricsGET /metrics/prometheusPrometheus metrics

Middleware

MiddlewareDescription
RateLimiterRequest rate limiting
ApiKeyAuthAPI key authentication
RequestIdRequest correlation ID
CorsCORS handling

Binaries

  • pisovereign-server - HTTP server binary

presentation_cli

Purpose: Command-line interface using Clap.

Dependencies: Core crates

Commands

CommandDescription
statusShow system status
chatSend chat message
commandExecute command
backupDatabase backup
restoreDatabase restore
migrateRun migrations
openapiExport OpenAPI spec
# Examples
pisovereign-cli status
pisovereign-cli chat "Hello"
pisovereign-cli command "briefing"
pisovereign-cli backup --output backup.db
pisovereign-cli openapi --output openapi.json

Binaries

  • pisovereign-cli - CLI binary

Cargo Docs

For detailed API documentation, see the auto-generated Cargo docs:

Generate locally:

just docs
# Opens browser at target/doc/presentation_http/index.html