openresponses_rust/types/
content.rs1use super::enums::ImageDetail;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5#[serde(tag = "type")]
6pub enum InputContent {
7 #[serde(rename = "input_text")]
8 Text { text: String },
9 #[serde(rename = "input_image")]
10 Image {
11 image_url: Option<String>,
12 #[serde(default)]
13 detail: ImageDetail,
14 },
15 #[serde(rename = "input_file")]
16 File {
17 filename: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 file_data: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 file_url: Option<String>,
22 },
23 #[serde(rename = "input_video")]
24 Video { video_url: String },
25}
26
27impl InputContent {
28 pub fn text<S: Into<String>>(text: S) -> Self {
29 InputContent::Text { text: text.into() }
30 }
31
32 pub fn image_url<S: Into<String>>(url: S) -> Self {
33 InputContent::Image {
34 image_url: Some(url.into()),
35 detail: ImageDetail::default(),
36 }
37 }
38
39 pub fn image_url_with_detail<S: Into<String>>(url: S, detail: ImageDetail) -> Self {
40 InputContent::Image {
41 image_url: Some(url.into()),
42 detail,
43 }
44 }
45
46 pub fn file_url<S: Into<String>>(url: S) -> Self {
47 InputContent::File {
48 filename: None,
49 file_data: None,
50 file_url: Some(url.into()),
51 }
52 }
53
54 pub fn file_data<S: Into<String>>(data: S, filename: Option<String>) -> Self {
55 InputContent::File {
56 filename,
57 file_data: Some(data.into()),
58 file_url: None,
59 }
60 }
61
62 pub fn video_url<S: Into<String>>(url: S) -> Self {
63 InputContent::Video {
64 video_url: url.into(),
65 }
66 }
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
70#[serde(tag = "type")]
71pub enum OutputContent {
72 #[serde(rename = "output_text")]
73 Text {
74 text: String,
75 #[serde(default)]
76 annotations: Vec<Annotation>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 logprobs: Option<Vec<LogProb>>,
79 },
80 #[serde(rename = "refusal")]
81 Refusal { refusal: String },
82 #[serde(rename = "text")]
83 PlainText { text: String },
84 #[serde(rename = "summary_text")]
85 SummaryText { text: String },
86 #[serde(rename = "reasoning_text")]
87 ReasoningText { text: String },
88}
89
90impl OutputContent {
91 pub fn text<S: Into<String>>(text: S) -> Self {
92 OutputContent::Text {
93 text: text.into(),
94 annotations: Vec::new(),
95 logprobs: None,
96 }
97 }
98
99 pub fn refusal<S: Into<String>>(text: S) -> Self {
100 OutputContent::Refusal {
101 refusal: text.into(),
102 }
103 }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
107#[serde(tag = "type")]
108pub enum Annotation {
109 #[serde(rename = "url_citation")]
110 UrlCitation {
111 url: String,
112 title: String,
113 start_index: i32,
114 end_index: i32,
115 },
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
119pub struct LogProb {
120 pub token: String,
121 pub logprob: f64,
122 pub bytes: Vec<u8>,
123 pub top_logprobs: Vec<TopLogProb>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
127pub struct TopLogProb {
128 pub token: String,
129 pub logprob: f64,
130 pub bytes: Vec<u8>,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
134#[serde(untagged)]
135pub enum Content {
136 Input(InputContent),
137 Output(OutputContent),
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
141#[serde(untagged)]
142pub enum ContentParam {
143 Array(Vec<InputContent>),
144 Single(String),
145}