Skip to main content

agentic_core/tool/
normalize.rs

1use crate::types::io::FunctionTool;
2use crate::types::io::input::FunctionToolResultMessage;
3use crate::types::tools::ResponsesTool;
4
5use super::codex::CodexNamespaceHandler;
6use super::handler::{ToolHandler, ToolOutput};
7use super::web_search::web_search_function_tool;
8
9impl ResponsesTool {
10    /// Normalise this tool declaration to the `FunctionTool` wire format that vLLM understands.
11    ///
12    /// - `Function` variants convert via [`From<&FunctionToolParam>`] for `FunctionTool`.
13    ///   Returns `None` and logs at `debug` level if the name is empty.
14    ///
15    /// This is the entry point called by `RequestPayload::to_upstream_request()` so that
16    /// vLLM always receives a `Vec<FunctionTool>`, never a raw `ResponsesTool` enum.
17    ///
18    /// # Panics
19    ///
20    /// Panics if serializing a `CodexNamespaceToolParam` fails, which cannot happen
21    /// for the derive-generated `Serialize` impl on that struct.
22    #[must_use]
23    pub fn to_function_tools(&self) -> Vec<FunctionTool> {
24        match self {
25            // name is NonEmptyToolName — empty names are rejected by serde at
26            // deserialization time, so no runtime check is needed here.
27            Self::Function(p) => vec![FunctionTool::from(p)],
28            Self::Mcp(p) => {
29                tracing::debug!(
30                    server_label = %p.server_label,
31                    "MCP tool skipped in normalize - handler not yet registered"
32                );
33                vec![]
34            }
35            Self::WebSearch(_) => vec![web_search_function_tool()],
36            Self::FileSearch(_) => {
37                tracing::debug!("file_search tool skipped in normalize - handler not yet registered");
38                vec![]
39            }
40            Self::CodeInterpreter(_) => {
41                tracing::debug!("code_interpreter tool skipped in normalize - handler not yet registered");
42                vec![]
43            }
44            Self::Namespace(p) => {
45                let param = serde_json::to_value(p).expect("serialization of known struct is infallible");
46                CodexNamespaceHandler.normalize(&param)
47            }
48            Self::Unknown => {
49                tracing::debug!("unknown tool skipped in normalize");
50                vec![]
51            }
52        }
53    }
54}
55
56impl From<ToolOutput> for FunctionToolResultMessage {
57    fn from(o: ToolOutput) -> Self {
58        Self {
59            call_id: o.call_id,
60            output: o.output,
61        }
62    }
63}