use std::collections::HashMap;
use std::sync::Arc;
#[derive(Clone)]
pub enum ResolvedTool {
ResponseFormat {
description: String,
schema: indexmap::IndexMap<String, serde_json::Value>,
},
Mcp {
connection: objectiveai_sdk::mcp::Connection,
tool: objectiveai_sdk::mcp::tool::Tool,
},
}
#[derive(Debug, thiserror::Error)]
#[error("MCP list_tools error ({url}): {error}")]
pub struct ResolveToolsError {
pub url: String,
pub error: Arc<objectiveai_sdk::mcp::Error>,
}
pub async fn resolve_tools(
mcp_connection: Option<&objectiveai_sdk::mcp::Connection>,
response_format: Option<&objectiveai_sdk::agent::completions::request::ResponseFormat>,
) -> Result<(Vec<String>, HashMap<String, ResolvedTool>), ResolveToolsError> {
let mut names = Vec::new();
let mut map = HashMap::new();
if let Some(connection) = mcp_connection {
let tools = connection.list_tools().await.map_err(|error| ResolveToolsError {
url: connection.url.clone(),
error,
})?;
for tool in tools.iter() {
names.push(tool.name.clone());
map.insert(
tool.name.clone(),
ResolvedTool::Mcp {
connection: connection.clone(),
tool: tool.clone(),
},
);
}
}
if let Some(objectiveai_sdk::agent::completions::request::ResponseFormat::ToolCall {
name,
description,
schema,
..
}) = response_format
{
names.push(name.clone());
map.insert(
name.clone(),
ResolvedTool::ResponseFormat {
description: description.clone(),
schema: schema.clone(),
},
);
}
Ok((names, map))
}
#[cfg(test)]
#[path = "resolved_tool_tests.rs"]
mod tests;