@@ -17,7 +17,6 @@ export const BatchTool = Tool.define("batch", async () => {
1717 } ) ,
1818 )
1919 . min ( 1 , "Provide at least one tool call" )
20- . max ( 10 , "Too many tools in batch. Maximum allowed is 10." )
2120 . describe ( "Array of tool calls to execute in parallel" ) ,
2221 } ) ,
2322 formatValidationError ( error ) {
@@ -34,34 +33,16 @@ export const BatchTool = Tool.define("batch", async () => {
3433 const { Session } = await import ( "../session" )
3534 const { Identifier } = await import ( "../id/id" )
3635
37- const toolCalls = params . tool_calls
36+ const toolCalls = params . tool_calls . slice ( 0 , 10 )
37+ const discardedCalls = params . tool_calls . slice ( 10 )
3838
3939 const { ToolRegistry } = await import ( "./registry" )
4040 const availableTools = await ToolRegistry . tools ( "" , "" )
4141 const toolMap = new Map ( availableTools . map ( ( t ) => [ t . id , t ] ) )
4242
43- const partIDs = new Map < ( typeof toolCalls ) [ 0 ] , string > ( )
44- for ( const call of toolCalls ) {
45- const partID = Identifier . ascending ( "part" )
46- partIDs . set ( call , partID )
47- Session . updatePart ( {
48- id : partID ,
49- messageID : ctx . messageID ,
50- sessionID : ctx . sessionID ,
51- type : "tool" ,
52- tool : call . tool ,
53- callID : partID ,
54- state : {
55- status : "pending" ,
56- input : call . parameters ,
57- raw : JSON . stringify ( call ) ,
58- } ,
59- } )
60- }
61-
6243 const executeCall = async ( call : ( typeof toolCalls ) [ 0 ] ) => {
6344 const callStartTime = Date . now ( )
64- const partID = partIDs . get ( call ) !
45+ const partID = Identifier . ascending ( "part" )
6546
6647 try {
6748 if ( DISALLOWED . has ( call . tool ) ) {
@@ -77,6 +58,22 @@ export const BatchTool = Tool.define("batch", async () => {
7758 }
7859 const validatedParams = tool . parameters . parse ( call . parameters )
7960
61+ await Session . updatePart ( {
62+ id : partID ,
63+ messageID : ctx . messageID ,
64+ sessionID : ctx . sessionID ,
65+ type : "tool" ,
66+ tool : call . tool ,
67+ callID : partID ,
68+ state : {
69+ status : "running" ,
70+ input : call . parameters ,
71+ time : {
72+ start : callStartTime ,
73+ } ,
74+ } ,
75+ } )
76+
8077 const result = await tool . execute ( validatedParams , { ...ctx , callID : partID } )
8178
8279 await Session . updatePart ( {
@@ -126,31 +123,48 @@ export const BatchTool = Tool.define("batch", async () => {
126123
127124 const results = await Promise . all ( toolCalls . map ( ( call ) => executeCall ( call ) ) )
128125
129- const successfulCalls = results . filter ( ( r ) => r . success ) . length
130- const failedCalls = toolCalls . length - successfulCalls
126+ // Add discarded calls as errors
127+ const now = Date . now ( )
128+ for ( const call of discardedCalls ) {
129+ const partID = Identifier . ascending ( "part" )
130+ await Session . updatePart ( {
131+ id : partID ,
132+ messageID : ctx . messageID ,
133+ sessionID : ctx . sessionID ,
134+ type : "tool" ,
135+ tool : call . tool ,
136+ callID : partID ,
137+ state : {
138+ status : "error" ,
139+ input : call . parameters ,
140+ error : "Maximum of 10 tools allowed in batch" ,
141+ time : { start : now , end : now } ,
142+ } ,
143+ } )
144+ results . push ( {
145+ success : false as const ,
146+ tool : call . tool ,
147+ error : new Error ( "Maximum of 10 tools allowed in batch" ) ,
148+ } )
149+ }
131150
132- const outputParts = results . map ( ( r ) => {
133- if ( r . success ) {
134- return `<tool_result name="${ r . tool } ">\n${ r . result . output } \n</tool_result>`
135- }
136- const errorMessage = r . error instanceof Error ? r . error . message : String ( r . error )
137- return `<tool_result name="${ r . tool } ">\nError: ${ errorMessage } \n</tool_result>`
138- } )
151+ const successfulCalls = results . filter ( ( r ) => r . success ) . length
152+ const failedCalls = results . length - successfulCalls
139153
140154 const outputMessage =
141155 failedCalls > 0
142- ? `Executed ${ successfulCalls } /${ toolCalls . length } tools successfully. ${ failedCalls } failed.\n\n ${ outputParts . join ( "\n\n" ) } `
143- : `All ${ successfulCalls } tools executed successfully.\n\n ${ outputParts . join ( "\n\n" ) } \n\ nKeep using the batch tool for optimal performance in your next response!`
156+ ? `Executed ${ successfulCalls } /${ results . length } tools successfully. ${ failedCalls } failed.`
157+ : `All ${ successfulCalls } tools executed successfully.\n\nKeep using the batch tool for optimal performance in your next response!`
144158
145159 return {
146- title : `Batch execution (${ successfulCalls } /${ toolCalls . length } successful)` ,
160+ title : `Batch execution (${ successfulCalls } /${ results . length } successful)` ,
147161 output : outputMessage ,
148162 attachments : results . filter ( ( result ) => result . success ) . flatMap ( ( r ) => r . result . attachments ?? [ ] ) ,
149163 metadata : {
150- totalCalls : toolCalls . length ,
164+ totalCalls : results . length ,
151165 successful : successfulCalls ,
152166 failed : failedCalls ,
153- tools : toolCalls . map ( ( c ) => c . tool ) ,
167+ tools : params . tool_calls . map ( ( c ) => c . tool ) ,
154168 details : results . map ( ( r ) => ( { tool : r . tool , success : r . success } ) ) ,
155169 } ,
156170 }
0 commit comments