#[doc(hidden)]
pub use llm_tool::__private;
pub use llm_tool::{
EmptyParams, Json, JsonSchema, RustTool, ToolContext, ToolDefinition, ToolError, ToolOutput,
ToolRegistry, definition_of,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolSource {
Builtin,
Custom,
Mcp,
}
impl std::fmt::Display for ToolSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Builtin => f.write_str("builtin"),
Self::Custom => f.write_str("custom"),
Self::Mcp => f.write_str("mcp"),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct AvailableTool {
pub name: String,
pub description: String,
pub parameter_schema: serde_json::Value,
pub source: ToolSource,
}
impl std::fmt::Display for AvailableTool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} [{}]", self.name, self.source)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tool_source_display() {
assert_eq!(ToolSource::Builtin.to_string(), "builtin");
assert_eq!(ToolSource::Custom.to_string(), "custom");
assert_eq!(ToolSource::Mcp.to_string(), "mcp");
}
#[test]
fn tool_source_serde_roundtrip() {
for source in [ToolSource::Builtin, ToolSource::Custom, ToolSource::Mcp] {
let json = serde_json::to_string(&source).unwrap();
let parsed: ToolSource = serde_json::from_str(&json).unwrap();
assert_eq!(parsed, source);
}
}
#[test]
fn tool_source_serializes_as_snake_case() {
assert_eq!(
serde_json::to_string(&ToolSource::Builtin).unwrap(),
"\"builtin\""
);
assert_eq!(
serde_json::to_string(&ToolSource::Custom).unwrap(),
"\"custom\""
);
assert_eq!(serde_json::to_string(&ToolSource::Mcp).unwrap(), "\"mcp\"");
}
#[test]
fn available_tool_display() {
let tool = AvailableTool {
name: "get_weather".to_owned(),
description: "Gets weather.".to_owned(),
parameter_schema: serde_json::Value::Null,
source: ToolSource::Mcp,
};
assert_eq!(tool.to_string(), "get_weather [mcp]");
}
#[test]
fn available_tool_serde_roundtrip() {
let tool = AvailableTool {
name: "view_file".to_owned(),
description: "Read file contents.".to_owned(),
parameter_schema: serde_json::json!({"type": "object"}),
source: ToolSource::Builtin,
};
let json = serde_json::to_string(&tool).unwrap();
let parsed: AvailableTool = serde_json::from_str(&json).unwrap();
assert_eq!(parsed.name, "view_file");
assert_eq!(parsed.source, ToolSource::Builtin);
assert!(!parsed.description.is_empty());
}
}