use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ToolCall {
pub id: String,
pub name: String,
pub arguments: String,
}
impl ToolCall {
pub fn new(
id: impl Into<String>,
name: impl Into<String>,
arguments: impl Into<String>,
) -> Self {
Self {
id: id.into(),
name: name.into(),
arguments: arguments.into(),
}
}
pub fn arg(&self, key: &str) -> Option<serde_json::Value> {
serde_json::from_str::<serde_json::Value>(&self.arguments)
.ok()
.and_then(|v| v.get(key).cloned())
}
pub fn input(&self) -> Option<String> {
self.arg("input").and_then(|v| match v {
serde_json::Value::String(s) => Some(s),
other => Some(other.to_string()),
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionDefinition {
pub name: String,
pub description: String,
pub parameters: serde_json::Value,
}
impl FunctionDefinition {
pub fn new(
name: impl Into<String>,
description: impl Into<String>,
parameters: serde_json::Value,
) -> Self {
Self {
name: name.into(),
description: description.into(),
parameters,
}
}
pub fn single_input(name: impl Into<String>, description: impl Into<String>) -> Self {
Self::new(
name,
description,
serde_json::json!({
"type": "object",
"properties": {
"input": {
"type": "string",
"description": "The input string"
}
},
"required": ["input"]
}),
)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ToolChoice {
Auto,
None,
Required,
Tool(String),
}