use agtrace_types::ToolCallPayload;
use serde_json::Value;
#[deprecated(
since = "0.3.0",
note = "Use ToolMapper::normalize_call instead. See function docs for migration path."
)]
pub fn normalize_tool_call(
name: String,
arguments: Value,
provider_call_id: Option<String>,
) -> ToolCallPayload {
match name.as_str() {
"Read" | "Glob" => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::FileRead {
name,
arguments: args,
provider_call_id,
};
}
}
"Edit" => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::FileEdit {
name,
arguments: args,
provider_call_id,
};
}
}
"Write" => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::FileWrite {
name,
arguments: args,
provider_call_id,
};
}
}
"Bash" | "KillShell" | "BashOutput" => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::Execute {
name,
arguments: args,
provider_call_id,
};
}
}
"Grep" | "WebSearch" | "WebFetch" => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::Search {
name,
arguments: args,
provider_call_id,
};
}
}
_ if name.starts_with("mcp__") => {
if let Ok(args) = serde_json::from_value(arguments.clone()) {
return ToolCallPayload::Mcp {
name,
arguments: args,
provider_call_id,
};
}
}
_ => {}
}
ToolCallPayload::Generic {
name,
arguments,
provider_call_id,
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[allow(deprecated)]
#[test]
fn test_normalize_file_read() {
let payload = normalize_tool_call(
"Read".to_string(),
json!({"file_path": "/path/to/file.rs"}),
Some("call_123".to_string()),
);
match payload {
ToolCallPayload::FileRead {
name,
arguments,
provider_call_id,
} => {
assert_eq!(name, "Read");
assert_eq!(arguments.path(), Some("/path/to/file.rs"));
assert_eq!(provider_call_id, Some("call_123".to_string()));
}
_ => panic!("Expected FileRead variant"),
}
}
#[allow(deprecated)]
#[test]
fn test_normalize_execute() {
let payload = normalize_tool_call(
"Bash".to_string(),
json!({"command": "ls -la"}),
Some("call_456".to_string()),
);
match payload {
ToolCallPayload::Execute {
name,
arguments,
provider_call_id,
} => {
assert_eq!(name, "Bash");
assert_eq!(arguments.command, Some("ls -la".to_string()));
assert_eq!(provider_call_id, Some("call_456".to_string()));
}
_ => panic!("Expected Execute variant"),
}
}
#[allow(deprecated)]
#[test]
fn test_normalize_mcp_tool() {
let payload = normalize_tool_call(
"mcp__o3__search".to_string(),
json!({"query": "test"}),
Some("call_789".to_string()),
);
match payload {
ToolCallPayload::Mcp {
name,
arguments,
provider_call_id,
} => {
assert_eq!(name, "mcp__o3__search");
assert_eq!(
arguments.inner.get("query").and_then(|v| v.as_str()),
Some("test")
);
assert_eq!(provider_call_id, Some("call_789".to_string()));
}
_ => panic!("Expected Mcp variant"),
}
}
#[allow(deprecated)]
#[test]
fn test_normalize_unknown_tool_fallback() {
let payload = normalize_tool_call(
"UnknownTool".to_string(),
json!({"foo": "bar"}),
Some("call_999".to_string()),
);
match payload {
ToolCallPayload::Generic {
name,
arguments,
provider_call_id,
} => {
assert_eq!(name, "UnknownTool");
assert_eq!(arguments, json!({"foo": "bar"}));
assert_eq!(provider_call_id, Some("call_999".to_string()));
}
_ => panic!("Expected Generic variant for unknown tool"),
}
}
#[allow(deprecated)]
#[test]
fn test_normalize_invalid_arguments_fallback() {
let payload = normalize_tool_call(
"Read".to_string(),
json!({"invalid_field": 123}),
Some("call_000".to_string()),
);
match payload {
ToolCallPayload::FileRead {
name, arguments, ..
} => {
assert_eq!(name, "Read");
assert_eq!(arguments.file_path, None);
assert_eq!(arguments.path, None);
assert_eq!(arguments.pattern, None);
assert_eq!(arguments.extra.get("invalid_field"), Some(&json!(123)));
}
_ => panic!("Expected FileRead variant, got: {:?}", payload.kind()),
}
}
}