codex_convert_proxy/convert/request/
tools.rs1use crate::types::chat_api::{ChatTool, ChatToolChoice, ChatToolChoiceMode, FunctionChoice, FunctionDefinition};
4use crate::types::response_api::{
5 Tool as ResponseTool, ToolChoice as ResponseToolChoice,
6 ToolType as ResponseToolType,
7};
8
9pub fn convert_tools(tools: Vec<ResponseTool>) -> Vec<ChatTool> {
11 tools
12 .into_iter()
13 .filter_map(|t| match t.tool_type {
14 ResponseToolType::Function | ResponseToolType::Custom | ResponseToolType::Other => {
15 Some(passthrough_tool(t))
16 }
17 ResponseToolType::WebSearchPreview => Some(builtin_tool(
18 t,
19 "web_search_preview",
20 "Web search tool",
21 serde_json::json!({
22 "type": "object",
23 "properties": {
24 "query": {
25 "type": "string",
26 "description": "The search query"
27 }
28 },
29 "required": ["query"]
30 }),
31 )),
32 ResponseToolType::CodeInterpreter => Some(builtin_tool(
33 t,
34 "code_interpreter",
35 "Code interpreter tool",
36 serde_json::json!({
37 "type": "object",
38 "properties": {
39 "code": {
40 "type": "string",
41 "description": "The code to execute"
42 }
43 },
44 "required": ["code"]
45 }),
46 )),
47 ResponseToolType::FileSearch => Some(builtin_tool(
48 t,
49 "file_search",
50 "File search tool",
51 serde_json::json!({
52 "type": "object",
53 "properties": {
54 "query": {
55 "type": "string",
56 "description": "The search query"
57 }
58 },
59 "required": ["query"]
60 }),
61 )),
62 ResponseToolType::Namespace => None,
63 })
64 .collect()
65}
66
67fn passthrough_tool(t: ResponseTool) -> ChatTool {
69 ChatTool {
70 tool_type: "function".to_string(),
71 function: FunctionDefinition {
72 name: t.name.unwrap_or_default(),
73 description: t.description,
74 parameters: t.parameters,
75 },
76 }
77}
78
79fn builtin_tool(
81 t: ResponseTool,
82 default_name: &str,
83 default_desc: &str,
84 param_schema: serde_json::Value,
85) -> ChatTool {
86 ChatTool {
87 tool_type: "function".to_string(),
88 function: FunctionDefinition {
89 name: t.name.unwrap_or_else(|| default_name.to_string()),
90 description: t.description.or_else(|| Some(default_desc.to_string())),
91 parameters: Some(param_schema),
92 },
93 }
94}
95
96pub fn convert_tool_choice(choice: ResponseToolChoice) -> ChatToolChoice {
98 match choice {
99 ResponseToolChoice::Auto => ChatToolChoice::Mode(ChatToolChoiceMode::Auto),
100 ResponseToolChoice::None => ChatToolChoice::Mode(ChatToolChoiceMode::None),
101 ResponseToolChoice::Required => ChatToolChoice::Mode(ChatToolChoiceMode::Required),
102 ResponseToolChoice::Function(f) => ChatToolChoice::Function(FunctionChoice { name: f.name }),
103 }
104}
105
106pub fn is_tool_choice_none(choice: &ChatToolChoice) -> bool {
108 match choice {
109 ChatToolChoice::Mode(mode) => *mode == ChatToolChoiceMode::None,
110 ChatToolChoice::Function(_) => false,
111 }
112}