openai_agents_rust/tools/
function.rs1use crate::agent::traits::AgentContext;
2use crate::error::AgentError;
3use crate::tools::traits::Tool;
4use async_trait::async_trait;
5use serde_json::json;
6
7pub struct FunctionTool<F>
8where
9 F: Fn(&str) -> Result<String, AgentError> + Send + Sync + 'static,
10{
11 name: String,
12 description: String,
13 func: F,
14 enabled: bool,
15}
16
17impl<F> FunctionTool<F>
18where
19 F: Fn(&str) -> Result<String, AgentError> + Send + Sync + 'static,
20{
21 pub fn new(name: impl Into<String>, description: impl Into<String>, func: F) -> Self {
22 Self {
23 name: name.into(),
24 description: description.into(),
25 func,
26 enabled: true,
27 }
28 }
29
30 pub fn disabled(mut self) -> Self {
31 self.enabled = false;
32 self
33 }
34}
35
36#[async_trait]
37impl<F> Tool for FunctionTool<F>
38where
39 F: Fn(&str) -> Result<String, AgentError> + Send + Sync + 'static,
40{
41 fn name(&self) -> &str {
42 &self.name
43 }
44 fn description(&self) -> &str {
45 &self.description
46 }
47 fn openai_tool_spec(&self) -> Option<serde_json::Value> {
48 Some(json!({
49 "type": "function",
50 "function": {
51 "name": self.name,
52 "description": self.description,
53 "parameters": {
54 "type": "object",
55 "properties": {
56 "text": {"type": "string", "description": "Text to transform."}
57 },
58 "required": ["text"],
59 "additionalProperties": false
60 }
61 }
62 }))
63 }
64 async fn is_enabled(&self, _ctx: &AgentContext) -> bool {
65 self.enabled
66 }
67 async fn call(&self, input: &str) -> Result<String, AgentError> {
68 (self.func)(input)
69 }
70 async fn call_with_context(
71 &self,
72 _ctx: &AgentContext,
73 _tool_call_id: Option<&str>,
74 input: &str,
75 ) -> Result<String, AgentError> {
76 (self.func)(input)
77 }
78}