agentic_core/tool/
normalize.rs1use crate::types::io::FunctionTool;
2use crate::types::io::input::FunctionToolResultMessage;
3use crate::types::tools::ResponsesTool;
4use crate::utils::common::serialize_to_value_or_custom_default;
5
6use super::codex::CodexNamespaceHandler;
7use super::custom::CustomHandler;
8use super::function::FunctionHandler;
9use super::handler::{ToolError, ToolHandler, ToolOutput};
10use super::mcp::McpHandler;
11use super::registry::ToolType;
12use super::web_search::web_search_function_tool;
13
14impl ResponsesTool {
15 pub fn validate(&self) -> Result<(), ToolError> {
22 match self {
23 Self::Function(param) => serialize_to_value_or_custom_default(
24 param,
25 "function tool config serialization failed",
26 |param| FunctionHandler.validate(¶m),
27 Err(ToolError::Config(
28 "function tool config serialization failed".to_owned(),
29 )),
30 ),
31 Self::Mcp(param) => serialize_to_value_or_custom_default(
32 param,
33 "MCP tool config serialization failed",
34 |param| McpHandler::spec_from_param(¶m).validate(¶m),
35 Err(ToolError::Config("MCP tool config serialization failed".to_owned())),
36 ),
37 Self::WebSearch(_) | Self::FileSearch(_) | Self::CodeInterpreter(_) | Self::Unknown => Ok(()),
38 Self::Namespace(param) => serialize_to_value_or_custom_default(
39 param,
40 "namespace tool config serialization failed",
41 |param| CodexNamespaceHandler.validate(¶m),
42 Err(ToolError::Config(
43 "namespace tool config serialization failed".to_owned(),
44 )),
45 ),
46 Self::Custom(param) => serialize_to_value_or_custom_default(
47 param,
48 "custom tool config serialization failed",
49 |param| CustomHandler.validate(¶m),
50 Err(ToolError::Config("custom tool config serialization failed".to_owned())),
51 ),
52 }
53 }
54
55 #[must_use]
57 pub fn tool_type(&self) -> Option<ToolType> {
58 match self {
59 Self::Function(_) => Some(ToolType::Function),
60 Self::Mcp(_) => Some(ToolType::Mcp),
61 Self::WebSearch(_) => Some(ToolType::WebSearch),
62 Self::FileSearch(_) => Some(ToolType::FileSearch),
63 Self::CodeInterpreter(_) => Some(ToolType::CodeInterpreter),
64 Self::Namespace(_) => Some(ToolType::CodexNamespace),
65 Self::Custom(_) => Some(ToolType::Custom),
66 Self::Unknown => None,
67 }
68 }
69
70 #[must_use]
71 pub fn is_gateway_owned(&self) -> bool {
72 self.tool_type().is_some_and(ToolType::is_gateway_owned)
73 }
74
75 #[must_use]
90 pub fn to_function_tools(&self) -> Vec<FunctionTool> {
91 match self {
92 Self::Function(p) => serialize_to_value_or_custom_default(
95 p,
96 "function tool config serialization failed",
97 |param| FunctionHandler.normalize(¶m).into_iter().take(1).collect(),
98 vec![],
99 ),
100 Self::Mcp(p) => serialize_to_value_or_custom_default(
101 p,
102 "MCP tool config serialization failed",
103 |param| McpHandler::spec_from_param(¶m).normalize(¶m),
104 vec![],
105 ),
106 Self::WebSearch(_) => vec![web_search_function_tool()],
107 Self::FileSearch(_) => {
108 tracing::debug!("file_search tool skipped in normalize - handler not yet registered");
109 vec![]
110 }
111 Self::CodeInterpreter(_) => {
112 tracing::debug!("code_interpreter tool skipped in normalize - handler not yet registered");
113 vec![]
114 }
115 Self::Namespace(p) => serialize_to_value_or_custom_default(
116 p,
117 "function tool config serialization failed",
118 |param| CodexNamespaceHandler.normalize(¶m),
119 vec![],
120 ),
121 Self::Custom(p) => serialize_to_value_or_custom_default(
122 p,
123 "custom tool config serialization failed",
124 |param| CustomHandler.normalize(¶m),
125 vec![],
126 ),
127 Self::Unknown => {
128 tracing::debug!("unknown tool skipped in normalize");
129 vec![]
130 }
131 }
132 }
133}
134
135impl From<ToolOutput> for FunctionToolResultMessage {
136 fn from(o: ToolOutput) -> Self {
137 Self {
138 call_id: o.call_id,
139 output: o.output.into(),
140 }
141 }
142}