@@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};
12
12
use serde_json:: json;
13
13
14
14
use crate :: types:: {
15
+ responses:: { self , Function , ToolDefinition } ,
15
16
ChatCompletionMessageToolCall , ChatCompletionMessageToolCallChunk ,
16
17
ChatCompletionRequestToolMessage , ChatCompletionTool , ChatCompletionToolType , FunctionCall ,
17
18
FunctionObject ,
@@ -29,7 +30,7 @@ pub trait Tool: Send + Sync {
29
30
30
31
/// Returns the name of the tool.
31
32
fn name ( ) -> String {
32
- Self :: Args :: schema_name ( )
33
+ Self :: Args :: schema_name ( ) . to_string ( )
33
34
}
34
35
35
36
/// Returns an optional description of the tool.
@@ -42,8 +43,8 @@ pub trait Tool: Send + Sync {
42
43
None
43
44
}
44
45
45
- /// Creates a ChatCompletionTool definition for the tool .
46
- fn definition ( ) -> ChatCompletionTool {
46
+ /// Returns the tool's definition for chat .
47
+ fn definition_for_chat ( ) -> ChatCompletionTool {
47
48
ChatCompletionTool {
48
49
r#type : ChatCompletionToolType :: Function ,
49
50
function : FunctionObject {
@@ -55,6 +56,16 @@ pub trait Tool: Send + Sync {
55
56
}
56
57
}
57
58
59
+ /// Returns the tool's definition for responses.
60
+ fn definition_for_responses ( ) -> ToolDefinition {
61
+ ToolDefinition :: Function ( Function {
62
+ name : Self :: name ( ) ,
63
+ description : Self :: description ( ) ,
64
+ parameters : json ! ( schema_for!( Self :: Args ) ) ,
65
+ strict : Self :: strict ( ) . unwrap_or ( false ) ,
66
+ } )
67
+ }
68
+
58
69
/// Executes the tool with the given arguments.
59
70
/// Returns a Future that resolves to either the tool's output or an error.
60
71
fn call (
@@ -66,8 +77,14 @@ pub trait Tool: Send + Sync {
66
77
/// A dynamic trait for tools that allows for runtime tool management.
67
78
/// This trait provides a way to work with tools without knowing their concrete types at compile time.
68
79
pub trait ToolDyn : Send + Sync {
69
- /// Returns the tool's definition as a ChatCompletionTool.
70
- fn definition ( & self ) -> ChatCompletionTool ;
80
+ /// Returns the tool's name.
81
+ fn name ( & self ) -> String ;
82
+
83
+ /// Returns the tool's definition for chat.
84
+ fn definition_for_chat ( & self ) -> ChatCompletionTool ;
85
+
86
+ /// Returns the tool's definition for responses.
87
+ fn definition_for_responses ( & self ) -> ToolDefinition ;
71
88
72
89
/// Executes the tool with the given JSON string arguments.
73
90
/// Returns a Future that resolves to either a JSON string output or an error string.
@@ -79,8 +96,16 @@ pub trait ToolDyn: Send + Sync {
79
96
80
97
// Implementation of ToolDyn for any type that implements Tool
81
98
impl < T : Tool > ToolDyn for T {
82
- fn definition ( & self ) -> ChatCompletionTool {
83
- T :: definition ( )
99
+ fn name ( & self ) -> String {
100
+ T :: name ( )
101
+ }
102
+
103
+ fn definition_for_chat ( & self ) -> ChatCompletionTool {
104
+ T :: definition_for_chat ( )
105
+ }
106
+
107
+ fn definition_for_responses ( & self ) -> ToolDefinition {
108
+ T :: definition_for_responses ( )
84
109
}
85
110
86
111
fn call (
@@ -125,29 +150,39 @@ impl ToolManager {
125
150
126
151
/// Adds a new tool to the manager.
127
152
pub fn add_tool < T : Tool + ' static > ( & mut self , tool : T ) {
128
- self . tools
129
- . insert ( T :: name ( ) , Arc :: new ( tool) ) ;
153
+ self . tools . insert ( T :: name ( ) , Arc :: new ( tool) ) ;
130
154
}
131
155
132
156
/// Adds a new tool with an Arc to the manager.
133
157
///
134
158
/// Use this if you want to access this tool after being added to the manager.
135
159
pub fn add_tool_dyn ( & mut self , tool : Arc < dyn ToolDyn > ) {
136
- self . tools . insert ( tool. definition ( ) . function . name , tool) ;
160
+ self . tools . insert ( tool. name ( ) , tool) ;
137
161
}
138
162
139
163
/// Removes a tool from the manager.
140
164
pub fn remove_tool ( & mut self , name : & str ) -> bool {
141
165
self . tools . remove ( name) . is_some ( )
142
166
}
143
167
144
- /// Returns the definitions of all tools in the manager.
145
- pub fn get_tools ( & self ) -> Vec < ChatCompletionTool > {
146
- self . tools . values ( ) . map ( |tool| tool. definition ( ) ) . collect ( )
168
+ /// Returns the definitions of all tools for chat in the manager.
169
+ pub fn get_tools_for_chat ( & self ) -> Vec < ChatCompletionTool > {
170
+ self . tools
171
+ . values ( )
172
+ . map ( |tool| tool. definition_for_chat ( ) )
173
+ . collect ( )
174
+ }
175
+
176
+ /// Returns the definitions of all tools for responses in the manager.
177
+ pub fn get_tools_for_responses ( & self ) -> Vec < ToolDefinition > {
178
+ self . tools
179
+ . values ( )
180
+ . map ( |tool| tool. definition_for_responses ( ) )
181
+ . collect ( )
147
182
}
148
183
149
- /// Executes multiple tool calls concurrently and returns their results.
150
- pub async fn call (
184
+ /// Executes multiple tool calls concurrently and returns their results for chat .
185
+ pub async fn call_for_chat (
151
186
& self ,
152
187
calls : impl IntoIterator < Item = ChatCompletionMessageToolCall > ,
153
188
) -> Vec < ChatCompletionRequestToolMessage > {
@@ -183,6 +218,46 @@ impl ToolManager {
183
218
}
184
219
outputs
185
220
}
221
+
222
+ /// Executes multiple tool calls concurrently and returns their results for responses.
223
+ pub async fn call_for_responses (
224
+ & self ,
225
+ calls : impl IntoIterator < Item = responses:: FunctionCall > ,
226
+ ) -> Vec < responses:: InputItem > {
227
+ let mut handles = Vec :: new ( ) ;
228
+ let mut outputs = Vec :: new ( ) ;
229
+
230
+ // Spawn a task for each tool call
231
+ for call in calls {
232
+ if let Some ( tool) = self . tools . get ( & call. name ) . cloned ( ) {
233
+ let handle = tokio:: spawn ( async move { tool. call ( call. arguments ) . await } ) ;
234
+ handles. push ( ( call. id , handle) ) ;
235
+ } else {
236
+ outputs. push ( responses:: InputItem :: Custom ( json ! ( {
237
+ "type" : "function_call_output" ,
238
+ "call_id" : call. call_id,
239
+ "output" : "Tool call failed: tool not found" ,
240
+ } ) ) ) ;
241
+ }
242
+ }
243
+
244
+ // Collect results from all spawned tasks
245
+ for ( id, handle) in handles {
246
+ let output = match handle. await {
247
+ Ok ( Ok ( output) ) => output,
248
+ Ok ( Err ( e) ) => {
249
+ format ! ( "Tool call failed: {}" , e)
250
+ }
251
+ Err ( _) => "Tool call failed: runtime error" . to_string ( ) ,
252
+ } ;
253
+ outputs. push ( responses:: InputItem :: Custom ( json ! ( {
254
+ "type" : "function_call_output" ,
255
+ "call_id" : id,
256
+ "output" : output,
257
+ } ) ) ) ;
258
+ }
259
+ outputs
260
+ }
186
261
}
187
262
188
263
/// A manager for handling streaming tool calls.
0 commit comments