use crate::types::chat_api::{ChatTool, ChatToolChoice, ChatToolChoiceMode, FunctionChoice, FunctionDefinition};
use crate::types::response_api::{
Tool as ResponseTool, ToolChoice as ResponseToolChoice,
ToolType as ResponseToolType,
};
pub fn convert_tools(tools: Vec<ResponseTool>) -> Vec<ChatTool> {
tools
.into_iter()
.filter_map(|t| match t.tool_type {
ResponseToolType::Function | ResponseToolType::Custom | ResponseToolType::Other => {
Some(passthrough_tool(t))
}
ResponseToolType::WebSearchPreview => Some(builtin_tool(
t,
"web_search_preview",
"Web search tool",
serde_json::json!({
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query"
}
},
"required": ["query"]
}),
)),
ResponseToolType::CodeInterpreter => Some(builtin_tool(
t,
"code_interpreter",
"Code interpreter tool",
serde_json::json!({
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The code to execute"
}
},
"required": ["code"]
}),
)),
ResponseToolType::FileSearch => Some(builtin_tool(
t,
"file_search",
"File search tool",
serde_json::json!({
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query"
}
},
"required": ["query"]
}),
)),
ResponseToolType::Namespace => None,
})
.collect()
}
fn passthrough_tool(t: ResponseTool) -> ChatTool {
ChatTool {
tool_type: "function".to_string(),
function: FunctionDefinition {
name: t.name.unwrap_or_default(),
description: t.description,
parameters: t.parameters,
},
}
}
fn builtin_tool(
t: ResponseTool,
default_name: &str,
default_desc: &str,
param_schema: serde_json::Value,
) -> ChatTool {
ChatTool {
tool_type: "function".to_string(),
function: FunctionDefinition {
name: t.name.unwrap_or_else(|| default_name.to_string()),
description: t.description.or_else(|| Some(default_desc.to_string())),
parameters: Some(param_schema),
},
}
}
pub fn convert_tool_choice(choice: ResponseToolChoice) -> ChatToolChoice {
match choice {
ResponseToolChoice::Auto => ChatToolChoice::Mode(ChatToolChoiceMode::Auto),
ResponseToolChoice::None => ChatToolChoice::Mode(ChatToolChoiceMode::None),
ResponseToolChoice::Required => ChatToolChoice::Mode(ChatToolChoiceMode::Required),
ResponseToolChoice::Function(f) => ChatToolChoice::Function(FunctionChoice { name: f.name }),
}
}
pub fn is_tool_choice_none(choice: &ChatToolChoice) -> bool {
match choice {
ChatToolChoice::Mode(mode) => *mode == ChatToolChoiceMode::None,
ChatToolChoice::Function(_) => false,
}
}