use std::fmt::Display;
use serde::{Deserialize, Serialize};
pub mod raw_macro;
pub mod serialise;
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ToolChoice {
pub function: FunctionCall,
#[serde(rename = "type")]
pub _type: ToolType,
}
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct FunctionCall {
pub name: String,
pub description: Option<String>,
pub parameters: Vec<FunctionParameter>,
}
impl Default for FunctionCall {
fn default() -> Self {
Self::new()
}
}
impl FunctionCall {
pub fn new() -> Self {
FunctionCall {
name: "".to_string(),
description: None,
parameters: vec![],
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum ToolType {
Function,
}
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct FunctionParameter {
pub name: String,
pub _type: FunctionType,
pub description: Option<String>,
#[serde(default = "default_required")]
pub required: bool,
}
fn default_required() -> bool {
true
}
impl Default for FunctionParameter {
fn default() -> Self {
Self {
name: String::new(),
_type: FunctionType::String,
description: None,
required: true,
}
}
}
impl FunctionParameter {
pub fn new(name: impl Into<String>, _type: FunctionType) -> Self {
Self {
name: name.into(),
_type,
description: None,
required: true,
}
}
pub fn description(mut self, d: impl Into<String>) -> Self {
self.description = Some(d.into());
self
}
pub fn required(mut self, v: bool) -> Self {
self.required = v;
self
}
}
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum FunctionType {
String,
Number,
Boolean,
Array(Box<FunctionType>),
Object(Vec<FunctionParameter>),
Null,
Enum(EnumValues),
Option(Box<FunctionType>),
Map(Box<FunctionType>),
OneOf(Vec<FunctionVariant>),
}
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct FunctionVariant {
pub name: String,
pub description: Option<String>,
pub parameters: Vec<FunctionParameter>,
}
impl Display for FunctionType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FunctionType::String => write!(f, "string"),
FunctionType::Number => write!(f, "number"),
FunctionType::Boolean => write!(f, "boolean"),
FunctionType::Array(_type) => write!(f, "array<{}>", _type),
FunctionType::Object { .. } => write!(f, "object"),
FunctionType::Null => write!(f, "null"),
FunctionType::Enum(values) => match values {
EnumValues::String(values) => {
write!(f, "enum<{}>", values.join(", "))
}
EnumValues::Int(values) => {
write!(
f,
"enum<{}>",
values
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
)
}
EnumValues::Float(values) => {
write!(
f,
"enum<{}>",
values
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(", ")
)
}
},
FunctionType::Option(value) => write!(f, "Option<{}>", value),
FunctionType::Map(value) => write!(f, "map<{}>", value),
FunctionType::OneOf(variants) => {
let names: Vec<_> = variants.iter().map(|v| v.name.as_str()).collect();
write!(f, "oneOf<{}>", names.join("|"))
}
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
pub enum EnumValues {
String(Vec<String>),
Int(Vec<i64>),
Float(Vec<f64>),
}
impl Display for EnumValues {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::String(value) => write!(f, "{:?}", value),
Self::Int(value) => write!(f, "{:?}", value),
Self::Float(value) => write!(f, "{:?}", value),
}
}
}