use objectiveai_sdk::mcp::shared::ResourceContentsUnion;
use objectiveai_sdk::mcp::tool::ContentBlock;
use rmcp::model::{
Annotated, Content, Meta, RawAudioContent, RawContent, RawResource, RawTextContent,
ResourceContents,
};
pub fn into_rmcp_content(block: ContentBlock) -> Content {
match block {
ContentBlock::Text(t) => Annotated {
raw: RawContent::Text(RawTextContent {
text: t.text,
meta: sdk_meta_to_rmcp(t._meta),
}),
annotations: None,
},
ContentBlock::Image(i) => Annotated {
raw: RawContent::Image(rmcp::model::RawImageContent {
data: i.data,
mime_type: i.mime_type,
meta: sdk_meta_to_rmcp(i._meta),
}),
annotations: None,
},
ContentBlock::Audio(a) => Annotated {
raw: RawContent::Audio(RawAudioContent {
data: a.data,
mime_type: a.mime_type,
}),
annotations: None,
},
ContentBlock::EmbeddedResource(er) => Annotated {
raw: RawContent::Resource(rmcp::model::RawEmbeddedResource {
resource: rcu_to_rmcp(er.resource),
meta: sdk_meta_to_rmcp(er._meta),
}),
annotations: None,
},
ContentBlock::ResourceLink(rl) => Annotated {
raw: RawContent::ResourceLink(RawResource {
uri: rl.uri,
name: rl.name,
title: rl.title,
description: rl.description,
mime_type: rl.mime_type,
size: None,
icons: None,
meta: sdk_meta_to_rmcp(rl._meta),
}),
annotations: None,
},
}
}
fn sdk_meta_to_rmcp(
meta: Option<indexmap::IndexMap<String, serde_json::Value>>,
) -> Option<Meta> {
meta.map(|m| {
let mut map = serde_json::Map::with_capacity(m.len());
for (k, v) in m {
map.insert(k, v);
}
Meta(map)
})
}
fn rcu_to_rmcp(rcu: ResourceContentsUnion) -> ResourceContents {
match rcu {
ResourceContentsUnion::Text(t) => ResourceContents::TextResourceContents {
uri: t.base.uri,
mime_type: t.base.mime_type,
text: t.text,
meta: sdk_meta_to_rmcp(t.base._meta),
},
ResourceContentsUnion::Blob(b) => ResourceContents::BlobResourceContents {
uri: b.base.uri,
mime_type: b.base.mime_type,
blob: b.blob,
meta: sdk_meta_to_rmcp(b.base._meta),
},
}
}