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
| Module | Description |
|---|---|
auth | Authentication and authorization logic |
compaction | Context compaction — summarizes old messages to reduce token usage |
context_guard | Enforces context window limits per model |
fallback | Fallback FSM — sequential/capability-matched provider fallback |
migration | Session and data migration utilities |
model_catalog | Model metadata registry (context windows, capabilities) |
prompt_builder | Assembles system + user + history into the final prompt |
routing | Routes messages to the correct channel/provider |
send_policy | Enforces send policies (rate limits, content filtering) |
system_prompt | System 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.