Skip to main content

gproxy_protocol/claude/common/tools/
dispatch.rs

1use serde::Deserialize;
2
3use super::Tool;
4
5impl<'de> Deserialize<'de> for Tool {
6    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
7        let value = serde_json::Value::deserialize(deserializer)?;
8        let type_ = value.get("type").and_then(serde_json::Value::as_str);
9        let known = match type_ {
10            Some(
11                "bash_20241022"
12                | "bash_20250124"
13                | "code_execution_20250522"
14                | "code_execution_20250825"
15                | "code_execution_20260120"
16                | "code_execution_20260521"
17                | "memory_20250818"
18                | "tool_search_tool_bm25_20251119"
19                | "tool_search_tool_bm25"
20                | "tool_search_tool_regex_20251119"
21                | "tool_search_tool_regex",
22            ) => decode(value, Tool::Command),
23            Some(
24                "text_editor_20241022"
25                | "text_editor_20250124"
26                | "text_editor_20250429"
27                | "text_editor_20250728",
28            ) => decode(value, Tool::TextEditor),
29            Some("computer_20241022" | "computer_20250124" | "computer_20251124") => {
30                decode(value, Tool::Computer)
31            }
32            Some("web_search_20250305" | "web_search_20260209" | "web_search_20260318") => {
33                decode(value, Tool::WebSearch)
34            }
35            Some(
36                "web_fetch_20250910" | "web_fetch_20260209" | "web_fetch_20260309"
37                | "web_fetch_20260318",
38            ) => decode(value, Tool::WebFetch),
39            Some("advisor_20260301") => decode(value, Tool::Advisor),
40            Some("mcp_toolset") => decode(value, Tool::McpToolset),
41            Some("custom") | None if value.get("input_schema").is_some() => {
42                decode(value, Tool::Custom)
43            }
44            _ => Ok(Tool::Unknown(value)),
45        };
46        known.map_err(serde::de::Error::custom)
47    }
48}
49
50fn decode<T>(
51    value: serde_json::Value,
52    wrap: impl FnOnce(T) -> Tool,
53) -> Result<Tool, serde_json::Error>
54where
55    T: serde::de::DeserializeOwned,
56{
57    serde_json::from_value(value).map(wrap)
58}