objectiveai_sdk/mcp/tool/
image.rs1use indexmap::IndexMap;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
9#[schemars(rename = "mcp.tool.ImageContent")]
10pub struct ImageContent {
11 pub data: String,
13 #[serde(rename = "mimeType")]
15 pub mime_type: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
18 #[schemars(extend("omitempty" = true))]
19 pub annotations: Option<super::super::shared::Annotations>,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 #[schemars(extend("omitempty" = true))]
23 pub _meta: Option<IndexMap<String, serde_json::Value>>,
24}
25
26#[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}