Skip to main content

objectiveai_sdk/mcp/tool/
image.rs

1//! Image content block.
2
3use indexmap::IndexMap;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7/// Image content (base64-encoded).
8#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
9#[schemars(rename = "mcp.tool.ImageContent")]
10pub struct ImageContent {
11    /// The base64-encoded image data.
12    pub data: String,
13    /// The MIME type of the image.
14    #[serde(rename = "mimeType")]
15    pub mime_type: String,
16    /// Optional annotations for the client.
17    #[serde(skip_serializing_if = "Option::is_none")]
18    #[schemars(extend("omitempty" = true))]
19    pub annotations: Option<super::super::shared::Annotations>,
20    /// Extension metadata.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    #[schemars(extend("omitempty" = true))]
23    pub _meta: Option<IndexMap<String, serde_json::Value>>,
24}
25
26/// Returned from [`TryFrom<&ImageUrl>`] for `ImageContent` when the
27/// source URL is not a `data:<mime>;base64,<payload>` URL — i.e. an
28/// http(s) or unknown-scheme URL that can't be inlined as base64.
29#[derive(Debug, thiserror::Error)]
30#[error("image url is not a base64 data URL: {url}")]
31pub struct ImageUrlNotDataUrl {
32    pub url: String,
33}
34
35impl TryFrom<crate::agent::completions::message::ImageUrl> for ImageContent {
36    type Error = ImageUrlNotDataUrl;
37
38    fn try_from(
39        image_url: crate::agent::completions::message::ImageUrl,
40    ) -> Result<Self, Self::Error> {
41        let parsed = image_url
42            .url
43            .strip_prefix("data:")
44            .and_then(|rest| rest.split_once(";base64,"))
45            .map(|(mime, data)| (mime.to_string(), data.to_string()));
46        match parsed {
47            Some((mime_type, data)) => Ok(Self {
48                data,
49                mime_type,
50                annotations: None,
51                _meta: None,
52            }),
53            None => Err(ImageUrlNotDataUrl { url: image_url.url }),
54        }
55    }
56}