pub enum Message {
System {
content: String,
},
User {
content: String,
},
UserMultimodal {
content: Vec<ContentBlock>,
},
Assistant {
content: String,
tool_calls: Vec<ToolCall>,
thinking: Vec<ThinkingBlock>,
},
ToolResult {
tool_use_id: String,
content: String,
provenance: Provenance,
},
ProviderOutputItems {
protocol: String,
items: Vec<Value>,
},
}Expand description
A message in a multi-turn conversation.
The System variant exists so callers can express a first-class
system prompt inside messages: Vec<Message> without threading it
through the legacy context: Option<String> field on the request.
Protocol handlers and local chat templates that have a native
system-role slot (OpenAI, Anthropic, Gemini, Gemma 4, Qwen) emit it
in the right place; ones that don’t can fold it into the first user
turn.
Variants§
System
A system prompt. Appears once, at the start of the conversation.
User
A user message (text only).
UserMultimodal
A user message with multimodal content (text + images + video + audio).
Fields
content: Vec<ContentBlock>Assistant
An assistant response, possibly with tool calls.
Fields
thinking: Vec<ThinkingBlock>Extended-thinking blocks produced on this turn, preserved so they can
be replayed VERBATIM on the next turn. Anthropic requires prior
thinking blocks — including their opaque signature and empty-text
blocks — be sent back unchanged, positioned before the tool_use
blocks, or the same-model turn 400s (“thinking must be preserved”).
Empty for providers/models without thinking. #[serde(default, skip_serializing_if)] keeps the wire + FFI backward-compatible: old
JSON without the field deserializes, and turns without thinking add
no bytes.
ToolResult
The result of executing a tool call.
Fields
provenance: ProvenanceWhere content came from, relative to the runtime’s trust boundary.
#[serde(default)] keeps the wire and oplog formats backward
compatible: transcripts recorded before this field existed
deserialize as Provenance::Internal, which is what they were.
ProviderOutputItems
Provider-specific output items that need to round-trip verbatim across turns. The OpenAI Responses API returns reasoning blobs, encrypted_content, web-search results, etc. as opaque structured items; the next request must include them in the same form to preserve provider-side state.
protocol identifies the provider format that produced the
items (currently "openai-responses"). Builder paths that
don’t recognize the protocol drop the variant — there is no
portable rendering across providers.