Skip to main content

opi_ai/
message.rs

1//! Provider-facing message types (S7.1).
2
3use serde::{Deserialize, Serialize};
4
5#[non_exhaustive]
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(tag = "role")]
8pub enum Message {
9    #[serde(rename = "user")]
10    User(UserMessage),
11    #[serde(rename = "assistant")]
12    Assistant(AssistantMessage),
13    #[serde(rename = "tool_result")]
14    ToolResult(ToolResultMessage),
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub struct UserMessage {
19    pub content: Vec<InputContent>,
20    pub timestamp_ms: i64,
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24pub struct AssistantMessage {
25    pub content: Vec<AssistantContent>,
26    pub api: crate::ApiKind,
27    pub provider: String,
28    pub model: String,
29    pub response_model: Option<String>,
30    pub response_id: Option<String>,
31    pub usage: crate::stream::Usage,
32    pub stop_reason: crate::stream::StopReason,
33    pub error_message: Option<String>,
34    pub timestamp_ms: i64,
35}
36
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38pub struct ToolResultMessage {
39    pub tool_call_id: String,
40    pub tool_name: String,
41    pub content: Vec<OutputContent>,
42    pub details: Option<serde_json::Value>,
43    pub is_error: bool,
44    pub timestamp_ms: i64,
45}
46
47/// Supported image media types for user-supplied images.
48#[non_exhaustive]
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50pub enum MediaType {
51    #[serde(rename = "image/png")]
52    Png,
53    #[serde(rename = "image/jpeg")]
54    Jpeg,
55    #[serde(rename = "image/gif")]
56    Gif,
57    #[serde(rename = "image/webp")]
58    WebP,
59}
60
61impl MediaType {
62    pub fn as_str(self) -> &'static str {
63        match self {
64            Self::Png => "image/png",
65            Self::Jpeg => "image/jpeg",
66            Self::Gif => "image/gif",
67            Self::WebP => "image/webp",
68        }
69    }
70}
71
72/// Source of image data: URL reference, base64-encoded string, or raw bytes.
73#[non_exhaustive]
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75#[serde(tag = "type")]
76pub enum ImageSource {
77    #[serde(rename = "url")]
78    Url { url: String },
79    #[serde(rename = "base64")]
80    Base64 { data: String },
81    #[serde(rename = "bytes")]
82    Bytes { data: Vec<u8> },
83}
84
85#[non_exhaustive]
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
87#[serde(tag = "type")]
88pub enum InputContent {
89    #[serde(rename = "text")]
90    Text { text: String },
91    #[serde(rename = "image")]
92    Image {
93        source: ImageSource,
94        media_type: MediaType,
95    },
96}
97
98#[non_exhaustive]
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
100#[serde(tag = "type")]
101pub enum AssistantContent {
102    #[serde(rename = "text")]
103    Text { text: String },
104    #[serde(rename = "thinking")]
105    Thinking { thinking: String },
106    #[serde(rename = "tool_call")]
107    ToolCall { tool_call: ToolCall },
108}
109
110#[non_exhaustive]
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112#[serde(tag = "type")]
113pub enum OutputContent {
114    #[serde(rename = "text")]
115    Text { text: String },
116    #[serde(rename = "image")]
117    Image {
118        source: ImageSource,
119        media_type: MediaType,
120    },
121}
122
123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124pub struct ToolCall {
125    pub id: String,
126    pub name: String,
127    pub arguments: String,
128}
129
130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
131pub struct ToolDef {
132    pub name: String,
133    pub description: String,
134    pub input_schema: serde_json::Value,
135}