systemprompt_models/wire/canonical/request/
content.rs1use serde_json::Value;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Role {
15 System,
16 User,
17 Assistant,
18 Tool,
19}
20
21impl Role {
22 pub const fn as_str(self) -> &'static str {
23 match self {
24 Self::System => "system",
25 Self::User => "user",
26 Self::Assistant => "assistant",
27 Self::Tool => "tool",
28 }
29 }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum ImageDetail {
34 Auto,
35 Low,
36 High,
37}
38
39impl ImageDetail {
40 pub const fn as_str(self) -> &'static str {
41 match self {
42 Self::Auto => "auto",
43 Self::Low => "low",
44 Self::High => "high",
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum CacheTtl {
51 FiveMinutes,
52 OneHour,
53}
54
55impl CacheTtl {
56 pub const fn as_str(self) -> &'static str {
57 match self {
58 Self::FiveMinutes => "5m",
59 Self::OneHour => "1h",
60 }
61 }
62
63 #[must_use]
64 pub fn parse(value: &str) -> Option<Self> {
65 match value {
66 "5m" => Some(Self::FiveMinutes),
67 "1h" => Some(Self::OneHour),
68 _ => None,
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
76pub struct CacheControl {
77 pub ttl: Option<CacheTtl>,
78}
79
80impl CacheControl {
81 pub const EPHEMERAL: Self = Self { ttl: None };
82
83 #[must_use]
84 pub const fn with_ttl(ttl: CacheTtl) -> Self {
85 Self { ttl: Some(ttl) }
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
90pub struct SystemBlock {
91 pub text: String,
92 pub cache_control: Option<CacheControl>,
93}
94
95impl SystemBlock {
96 #[must_use]
97 pub fn text(text: impl Into<String>) -> Self {
98 Self {
99 text: text.into(),
100 cache_control: None,
101 }
102 }
103}
104
105#[derive(Debug, Clone)]
106pub enum ImageSource {
107 Base64 {
108 media_type: String,
109 data: String,
110 detail: Option<ImageDetail>,
111 },
112 Url {
113 url: String,
114 detail: Option<ImageDetail>,
115 },
116}
117
118#[derive(Debug, Clone)]
119pub enum CanonicalContent {
120 Text {
121 text: String,
122 cache_control: Option<CacheControl>,
123 },
124 Image {
125 source: ImageSource,
126 cache_control: Option<CacheControl>,
127 },
128 ToolUse {
129 id: String,
130 name: String,
131 input: Value,
133 signature: Option<String>,
135 cache_control: Option<CacheControl>,
136 },
137 ToolResult {
138 tool_use_id: String,
139 content: Vec<Self>,
140 is_error: bool,
141 structured_content: Option<Value>,
142 meta: Option<Value>,
144 cache_control: Option<CacheControl>,
145 },
146 Thinking {
147 text: String,
148 signature: Option<String>,
149 id: Option<String>,
152 encrypted_content: Option<String>,
153 },
154}
155
156impl CanonicalContent {
157 #[must_use]
158 pub fn text(text: impl Into<String>) -> Self {
159 Self::Text {
160 text: text.into(),
161 cache_control: None,
162 }
163 }
164
165 #[must_use]
166 pub const fn image(source: ImageSource) -> Self {
167 Self::Image {
168 source,
169 cache_control: None,
170 }
171 }
172
173 #[must_use]
175 pub const fn cache_control(&self) -> Option<CacheControl> {
176 match self {
177 Self::Text { cache_control, .. }
178 | Self::Image { cache_control, .. }
179 | Self::ToolUse { cache_control, .. }
180 | Self::ToolResult { cache_control, .. } => *cache_control,
181 Self::Thinking { .. } => None,
182 }
183 }
184}
185
186#[derive(Debug, Clone)]
187pub struct CanonicalMessage {
188 pub role: Role,
189 pub content: Vec<CanonicalContent>,
190}