Skip to main content

clawdesk-domain

Core business logic for ClawDesk. Contains domain services like authentication, context management, prompt building, routing, and the fallback state machine. This crate depends only on clawdesk-types and defines traits that infrastructure crates implement.

Dependencies

Internal: clawdesk-types

External: async-trait, thiserror, tracing, chrono, uuid

Modules

ModuleDescription
authAuthentication and authorization logic
compactionContext compaction — summarizes old messages to reduce token usage
context_guardEnforces context window limits per model
fallbackFallback FSM — sequential/capability-matched provider fallback
migrationSession and data migration utilities
model_catalogModel metadata registry (context windows, capabilities)
prompt_builderAssembles system + user + history into the final prompt
routingRoutes messages to the correct channel/provider
send_policyEnforces send policies (rate limits, content filtering)
system_promptSystem prompt management and templating

Key Types & Traits

/// Builds the final prompt from session context
pub struct PromptBuilder {
pub system_prompt: SystemPrompt,
pub context_guard: ContextGuard,
pub compaction: CompactionStrategy,
}

/// Fallback state machine for provider selection
pub struct FallbackChain {
providers: Vec<ProviderRef>,
strategy: FallbackStrategy,
}

#[derive(Debug, Clone)]
pub enum FallbackStrategy {
Sequential,
CapabilityMatch,
RoundRobin,
}

/// Context window guard
pub struct ContextGuard {
pub max_tokens: usize,
pub reserved_output: usize,
pub reserved_system: usize,
}

impl ContextGuard {
/// Returns the available token budget for conversation history
pub fn available_budget(&self) -> usize {
self.max_tokens
.saturating_sub(self.reserved_output)
.saturating_sub(self.reserved_system)
}
}

Example Usage

use clawdesk_domain::{PromptBuilder, ContextGuard, FallbackChain, FallbackStrategy};

// Build a prompt with context window protection
let guard = ContextGuard {
max_tokens: 200_000,
reserved_output: 4096,
reserved_system: 1000,
};

let budget = guard.available_budget(); // 194_904

// Configure fallback
let fallback = FallbackChain::new(
vec![anthropic_ref, openai_ref, ollama_ref],
FallbackStrategy::Sequential,
);
tip

The domain crate contains no I/O code. All external interactions are behind traits, following the hexagonal architecture pattern.