async_gemini/models/
generate_content.rs

1use serde::{Deserialize, Deserializer, Serialize};
2
3use crate::util::deserialize_obj_or_vec;
4
5pub mod request;
6pub mod response;
7pub use request::*;
8pub use response::*;
9
10#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
11pub struct Content {
12    //todo: it can be option?
13    #[serde(deserialize_with = "deserialize_role")]
14    pub role: Role,
15    #[serde(deserialize_with = "deserialize_obj_or_vec")]
16    pub parts: Vec<Part>,
17}
18
19///The role in a conversation associated with the content. Specifying a role is required even in singleturn use cases. Acceptable values include the following:
20///USER: Specifies content that's sent by you.
21///MODEL: Specifies the model's response.
22#[derive(Debug, Serialize, Deserialize, Clone, Default, Copy, PartialEq, Eq)]
23#[serde(rename_all = "lowercase")]
24pub enum Role {
25    #[default]
26    User,
27    Model,
28}
29
30fn deserialize_role<'de, D>(deserializer: D) -> Result<Role, D::Error>
31where
32    D: Deserializer<'de>,
33{
34    let s = String::deserialize(deserializer)?;
35    let ss = s.to_lowercase();
36    match ss.as_str() {
37        "user" => Ok(Role::User),
38        "model" => Ok(Role::Model),
39        _ => Err(serde::de::Error::custom("Invalid value for Role")),
40    }
41}
42
43/// Ordered parts that make up the input. Parts may have different MIME types.
44/// For gemini-1.0-pro, only the text field is valid. The token limit is 32k.
45/// For gemini-1.0-pro-vision, you may specify either text only, text and up to 16 images, or text and 1 video. The token limit is 16k.
46#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
47pub enum Part {
48    /// The text instructions or chat dialogue to include in the prompt.
49    #[serde(rename = "text")]
50    Text(String),
51    /// Serialized bytes data of the image or video. You can specify at most 1 image with inlineData. To specify up to 16 images, use fileData.
52    #[serde(rename = "inlineData")]
53    Inline(InlineData),
54    #[serde(rename = "functionCall")]
55    FunctionCall(FunctionCall),
56    #[serde(rename = "functionResponse")]
57    FunctionResponse(FunctionResponse),
58    #[serde(rename = "fileData")]
59    File(FileData),
60}
61
62impl Part {
63    pub fn is_empty(&self) -> bool {
64        match self {
65            Part::Text(s) => s.trim().is_empty(),
66            Part::Inline(data) => data.data.trim().is_empty(),
67            Part::FunctionCall(call) => call.name.trim().is_empty(),
68            Part::FunctionResponse(response) => {
69                response.name.trim().is_empty() || response.response.is_null()
70            }
71            Part::File(file) => file.file_uri.trim().is_empty() || file.mime_type.trim().is_empty(),
72        }
73    }
74}
75
76#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
77#[serde(rename_all = "camelCase")]
78pub struct InlineData {
79    /// The media type of the image or video specified in the data or fileUri fields. Acceptable values include the following:
80    ///
81    /// image/png
82    /// image/jpeg
83    /// video/mov
84    /// video/mpeg
85    /// video/mp4
86    /// video/mpg
87    /// video/avi
88    /// video/wmv
89    /// video/mpegps
90    /// video/flv
91    ///
92    ///
93    /// Maximum video length: 2 minutes.
94    ///
95    /// No limit on image resolution.
96    pub mime_type: String,
97    /// The base64 encoding of the image or video to include inline in the prompt. When including media inline, you must also specify MIMETYPE.
98    /// size limit: 20MB
99    pub data: String,
100    pub video_metadata: Option<VideoMetadata>,
101}
102
103/// A predicted FunctionCall returned from the model that contains a string representing the FunctionDeclaration.name with the arguments and their values.
104#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
105pub struct FunctionCall {
106    /// Required. The name of the function to call. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 63.
107    pub name: String,
108    /// Optional. The function parameters and values in JSON object format.
109    pub args: Option<serde_json::Value>,
110}
111
112/// Required. The name of the function to call. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 63.
113#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
114pub struct FunctionResponse {
115    name: String,
116    response: serde_json::Value,
117}
118
119#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
120#[serde(rename_all = "camelCase")]
121pub struct FileData {
122    pub mime_type: String,
123    ///The Cloud Storage URI of the image or video to include in the prompt. The bucket that stores the file must be in the same Google Cloud project that's sending the request. You must also specify MIMETYPE.
124    ///size limit: 20MB
125    pub file_uri: String,
126    pub video_metadata: Option<VideoMetadata>,
127}
128
129/// Optional. For video input, the start and end offset of the video in Duration format. For example, to specify a 10 second clip starting at 1:00, set "start_offset": { "seconds": 60 } and "end_offset": { "seconds": 70 }.
130#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
131pub struct VideoMetadata {
132    pub start_offset: VideoOffset,
133    pub end_offset: VideoOffset,
134}
135
136#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
137pub struct VideoOffset {
138    pub seconds: i64,
139    pub nanos: i32,
140}
141
142/// The category of a rating.
143/// These categories cover various kinds of harms that developers may wish to adjust.
144#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
145pub enum HarmCategory {
146    /// Sexually explicit content.
147    #[serde(rename = "HARM_CATEGORY_SEXUALLY_EXPLICIT")]
148    SexuallyExplicit,
149
150    /// Hate speech and content.
151    #[serde(rename = "HARM_CATEGORY_HATE_SPEECH")]
152    HateSpeech,
153
154    /// Harassment content.
155    #[serde(rename = "HARM_CATEGORY_HARASSMENT")]
156    Harassment,
157
158    /// Dangerous content.
159    #[serde(rename = "HARM_CATEGORY_DANGEROUS_CONTENT")]
160    DangerousContent,
161}