Types (cersei-types)
Provider-agnostic core types — messages, content blocks, errors, stream events.
cersei-types
Provider-agnostic types shared across all Cersei crates.
Message
pub struct Message {
pub role: Role,
pub content: MessageContent,
pub metadata: Option<MessageMetadata>,
}
pub enum Role {
User,
Assistant,
System,
}Construct messages with helpers:
Message::user("Hello")
Message::assistant("Hi there!")
Message::system("You are helpful.")
message.get_text() // -> Option<&str>
// Multimodal: text + files (images, video, audio, PDFs) in one call.
Message::user_with_files("Describe these", &["diagram.png", "clip.mp4"])?;
Message::user_with_media("Caption", vec![ContentBlock::from_path("a.png")?]);See Multimodal Input for the full file-passing API.
ContentBlock
pub enum ContentBlock {
Text { text: String },
Image { source: ImageSource },
ToolUse { id: String, name: String, input: Value },
ToolResult { tool_use_id: String, content: ToolResultContent, is_error: Option<bool> },
Thinking { thinking: String, signature: String },
RedactedThinking { data: String },
Document { source: DocumentSource, title: Option<String>, context: Option<String>, citations: Option<CitationsConfig> },
Opaque,
}
// Image / document payloads carry inline base64 *or* a URL.
pub struct ImageSource {
pub source_type: String, // "base64" | "url"
pub media_type: Option<String>, // e.g. "image/png", "video/mp4"
pub data: Option<String>, // base64 (when source_type = "base64")
pub url: Option<String>, // remote URL (when source_type = "url")
}
// DocumentSource has the same shape, for PDFs/text.Build them with the high-level constructors instead of by hand:
ContentBlock::from_path("photo.jpg")?; // read file, sniff MIME, base64
ContentBlock::image_bytes("image/png", &bytes); // from raw bytes you hold
ContentBlock::image_url("https://x/y.png"); // remote image
ContentBlock::document_bytes("application/pdf", &pdf);Usage
pub struct Usage {
pub input_tokens: u64,
pub output_tokens: u64,
pub cache_creation_input_tokens: u64,
pub cache_read_input_tokens: u64,
pub cost_usd: Option<f64>,
}Supports merging:
usage.merge(&other_usage);StopReason
pub enum StopReason {
EndTurn,
MaxTokens,
ToolUse,
StopSequence,
}StreamEvent
Events emitted during streaming completion:
pub enum StreamEvent {
MessageStart { id: String, model: String },
ContentBlockStart { index: usize, block_type: String, id: Option<String>, name: Option<String> },
TextDelta { index: usize, text: String },
InputJsonDelta { index: usize, partial_json: String },
ThinkingDelta { index: usize, thinking: String },
ContentBlockStop { index: usize },
MessageDelta { stop_reason: Option<StopReason>, usage: Option<Usage> },
MessageStop,
Ping,
Error { message: String },
}CerseiError
pub enum CerseiError {
Auth(String),
Provider(String),
Tool(String),
Memory(String),
Http(reqwest::Error),
Json(serde_json::Error),
Io(std::io::Error),
Cancelled,
Other(anyhow::Error),
}All errors implement std::error::Error. Use Result<T> which is std::result::Result<T, CerseiError>.