Cersei

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>.

On this page