//! Tool definition: schema, parameters, and OpenAI-compatible tool objects. use async_openai::types::chat::{ChatCompletionTool, FunctionObject}; use serde::{Deserialize, Serialize}; /// A JSON Schema parameter definition for a tool argument. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ToolParam { pub name: String, #[serde(rename = "type")] pub param_type: String, pub description: Option, pub required: bool, #[serde(skip_serializing_if = "Option::is_none")] pub properties: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub items: Option>, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ToolSchema { #[serde(rename = "type", default)] pub schema_type: String, #[serde(skip_serializing_if = "Option::is_none")] pub properties: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub required: Option>, } impl Default for ToolSchema { fn default() -> Self { Self { schema_type: "object".to_string(), properties: None, required: None, } } } /// A tool definition with schema and metadata. #[derive(Debug, Clone)] pub struct ToolDefinition { pub name: String, pub description: Option, pub parameters: Option, pub strict: bool, } impl ToolDefinition { pub fn new(name: impl Into) -> Self { Self { name: name.into(), description: None, parameters: None, strict: false, } } pub fn description(mut self, description: impl Into) -> Self { self.description = Some(description.into()); self } pub fn parameters(mut self, schema: ToolSchema) -> Self { self.parameters = Some(schema); self } pub fn strict(mut self) -> Self { self.strict = true; self } pub fn to_openai_tool(&self) -> ChatCompletionTool { let parameters = self .parameters .as_ref() .map(|s| serde_json::to_value(s).unwrap_or(serde_json::Value::Null)); ChatCompletionTool { function: FunctionObject { name: self.name.clone(), description: self.description.clone(), parameters, strict: if self.strict { Some(true) } else { None }, }, } } }