Skip to main content

a3s_code_core/
tool_name.rs

1//! Canonical tool-name helpers shared by permission matching and the registry.
2
3/// Strip OpenAI-style `functions.` prefixes so policy rules like `Read(*)`
4/// and registry keys like `read` match model-emitted names such as
5/// `functions.read` (including nested `batch` calls).
6pub fn canonical_tool_name(name: &str) -> &str {
7    const PREFIX: &str = "functions.";
8    if name.len() > PREFIX.len() && name[..PREFIX.len()].eq_ignore_ascii_case(PREFIX) {
9        &name[PREFIX.len()..]
10    } else {
11        name
12    }
13}
14
15#[cfg(test)]
16mod tests {
17    use super::canonical_tool_name;
18
19    #[test]
20    fn strips_functions_prefix_case_insensitively() {
21        assert_eq!(canonical_tool_name("functions.read"), "read");
22        assert_eq!(canonical_tool_name("Functions.Read"), "Read");
23        assert_eq!(canonical_tool_name("FUNCTIONS.LS"), "LS");
24        assert_eq!(canonical_tool_name("read"), "read");
25        assert_eq!(
26            canonical_tool_name("mcp__server__tool"),
27            "mcp__server__tool"
28        );
29        assert_eq!(canonical_tool_name("functions."), "functions.");
30    }
31}