1use serde::{de::DeserializeOwned, Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ToolCall {
15 pub id: String,
17
18 #[serde(rename = "type")]
20 pub tool_type: String,
21
22 pub function: FunctionCall,
24}
25
26impl ToolCall {
27 pub fn new(
29 id: impl Into<String>,
30 name: impl Into<String>,
31 arguments: impl Into<String>,
32 ) -> Self {
33 Self {
34 id: id.into(),
35 tool_type: "function".to_string(),
36 function: FunctionCall {
37 name: name.into(),
38 arguments: arguments.into(),
39 },
40 }
41 }
42
43 pub fn name(&self) -> &str {
45 &self.function.name
46 }
47
48 pub fn arguments(&self) -> &str {
50 &self.function.arguments
51 }
52
53 pub fn parse_arguments<T: DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
55 serde_json::from_str(&self.function.arguments)
56 }
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct FunctionCall {
62 pub name: String,
64
65 pub arguments: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ToolCallResult {
72 pub tool_call_id: String,
74
75 pub role: String,
77
78 pub content: String,
80}
81
82impl ToolCallResult {
83 pub fn new(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
85 Self {
86 tool_call_id: tool_call_id.into(),
87 role: "tool".to_string(),
88 content: content.into(),
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use serde_json::json;
97 use std::collections::HashMap;
98
99 #[test]
100 fn test_tool_call() {
101 let call = ToolCall::new(
102 "call_123",
103 "calculator",
104 json!({"expression": "2 + 3"}).to_string(),
105 );
106
107 assert_eq!(call.id, "call_123");
108 assert_eq!(call.name(), "calculator");
109
110 let args: HashMap<String, String> = call.parse_arguments().unwrap();
111 assert_eq!(args.get("expression").unwrap(), "2 + 3");
112 }
113
114 #[test]
115 fn test_tool_call_result() {
116 let result = ToolCallResult::new("call_123", "5");
117
118 assert_eq!(result.tool_call_id, "call_123");
119 assert_eq!(result.role, "tool");
120 assert_eq!(result.content, "5");
121 }
122}