use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDefinition {
pub name: String,
pub description: String,
pub parameters: Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub strict: Option<bool>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(from = "ToolCallWire")]
pub struct ToolCall {
pub id: String,
pub function_name: String,
pub arguments: Value,
}
impl Serialize for ToolCall {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let wire = ToolCallWire {
id: self.id.clone(),
tool_type: "function".to_string(),
function: ToolCallFunctionWire {
name: self.function_name.clone(),
arguments: serde_json::to_string(&self.arguments).unwrap_or_default(),
},
};
wire.serialize(serializer)
}
}
#[derive(Serialize, Deserialize)]
struct ToolCallWire {
id: String,
#[serde(rename = "type")]
tool_type: String,
function: ToolCallFunctionWire,
}
#[derive(Serialize, Deserialize)]
struct ToolCallFunctionWire {
name: String,
arguments: String,
}
impl From<ToolCallWire> for ToolCall {
fn from(wire: ToolCallWire) -> Self {
ToolCall {
id: wire.id,
function_name: wire.function.name,
arguments: serde_json::from_str(&wire.function.arguments).unwrap_or(Value::Null),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolResult {
pub tool_call_id: String,
pub content: String,
#[serde(default)]
pub is_error: bool,
}