use serde::Deserialize;
use serde::Serialize;
use crate::json::JsonObject;
use crate::json::JsonValue;
use crate::shared::ProviderOptions;
use crate::shared::ToolName;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
#[non_exhaustive]
pub enum ToolDefinition {
Function {
name: ToolName,
#[serde(default, skip_serializing_if = "Option::is_none")]
description: Option<String>,
input_schema: JsonValue,
#[serde(default, skip_serializing_if = "Option::is_none")]
strict: Option<bool>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
input_examples: Vec<JsonObject>,
#[serde(default, skip_serializing_if = "Option::is_none")]
provider_options: Option<ProviderOptions>,
},
Provider {
id: String,
name: ToolName,
#[serde(default)]
args: JsonObject,
},
}
impl ToolDefinition {
#[must_use]
pub fn function(
name: impl Into<ToolName>,
description: Option<String>,
input_schema: JsonValue,
) -> Self {
Self::Function {
name: name.into(),
description,
input_schema,
strict: None,
input_examples: Vec::new(),
provider_options: None,
}
}
#[must_use]
pub fn provider(id: impl Into<String>, name: impl Into<ToolName>, args: JsonObject) -> Self {
Self::Provider {
id: id.into(),
name: name.into(),
args,
}
}
#[must_use]
pub fn name(&self) -> &ToolName {
match self {
Self::Function { name, .. } | Self::Provider { name, .. } => name,
}
}
#[must_use]
pub fn is_provider_tool(&self) -> bool {
matches!(self, Self::Provider { .. })
}
}