11import Foundation
22
33extension Agent {
4- func tool( named name: String ) -> ( any AnyTool < C > ) ? {
5- tools. first ( where: { $0. name == name } )
6- }
7-
84 func resolveTimeout( for call: ToolCall ) -> Duration {
9- guard let tool = tool ( named: call. name) else {
5+ guard let tool = firstTool ( named: call. name, in : tools ) else {
106 return configuration. toolTimeout
117 }
128 return resolvedToolTimeout ( for: tool, default: configuration. toolTimeout)
139 }
1410
15- func withTimeout< T: Sendable > (
16- _ timeout: Duration ,
17- toolName: String ,
18- operation: @Sendable @escaping ( ) async throws -> T
19- ) async throws -> T {
20- try await withThrowingTaskGroup ( of: T . self) { group in
21- group. addTask { try await operation ( ) }
22- group. addTask {
23- try await Task . sleep ( for: timeout)
24- throw AgentError . toolTimeout ( tool: toolName)
25- }
26- guard let result = try await group. next ( ) else {
27- preconditionFailure ( " ThrowingTaskGroup with two tasks must yield a result " )
28- }
29- group. cancelAll ( )
30- return result
31- }
32- }
33-
3411 func executeWithTimeout(
3512 _ call: ToolCall , context: C , approvalHandler: ToolApprovalHandler ? = nil
3613 ) async throws -> ToolResult {
3714 do {
38- return try await withTimeout ( resolveTimeout ( for: call) , toolName: call. name) {
15+ return try await withToolTimeout ( resolveTimeout ( for: call) , toolName: call. name) {
3916 if let handler = approvalHandler,
40- let approvalAware = self . tool ( named: call. name) as? any ApprovalAwareSubAgentTool < C > {
17+ let tool = firstTool ( named: call. name, in: self . tools) ,
18+ let approvalAware = tool as? any ApprovalAwareSubAgentTool < C > {
4119 return try await approvalAware. executeWithApproval (
4220 arguments: call. argumentsData, context: context, approvalHandler: handler
4321 )
@@ -73,7 +51,7 @@ extension Agent {
7351
7452 let result : ToolResult
7553 do {
76- result = try await withTimeout ( resolveTimeout ( for: call) , toolName: call. name) {
54+ result = try await withToolTimeout ( resolveTimeout ( for: call) , toolName: call. name) {
7755 try await tool. executeStreaming (
7856 toolCallId: call. id, arguments: call. argumentsData,
7957 context: context, parentSessionID: eventFactory. sessionID,
@@ -108,7 +86,7 @@ extension Agent {
10886 ) )
10987 } else {
11088 let call = wave. calls [ 0 ]
111- let result : ToolResult = if let streamableTool = tool ( named: call. name)
89+ let result : ToolResult = if let streamableTool = firstTool ( named: call. name, in : tools )
11290 as? any StreamableSubAgentTool < C > {
11391 try await executeStreamableWithTimeout (
11492 call, tool: streamableTool, context: context,
@@ -150,7 +128,7 @@ extension Agent {
150128 }
151129
152130 func executeTool( _ call: ToolCall , context: C ) async throws -> ToolResult {
153- guard let tool = tool ( named: call. name) else {
131+ guard let tool = firstTool ( named: call. name, in : tools ) else {
154132 throw AgentError . toolNotFound ( name: call. name)
155133 }
156134 return try await tool. execute ( arguments: call. argumentsData, context: context)
@@ -161,7 +139,7 @@ extension Agent {
161139 var waves : [ ExecutionWave ] = [ ]
162140 var safeBatch : [ ToolCall ] = [ ]
163141 for call in calls {
164- if tool ( named: call. name) ? . isConcurrencySafe ?? false {
142+ if firstTool ( named: call. name, in : tools ) ? . isConcurrencySafe ?? false {
165143 safeBatch. append ( call)
166144 } else {
167145 if !safeBatch. isEmpty {
@@ -210,7 +188,7 @@ extension Agent {
210188 return try await withThrowingTaskGroup ( of: ( Int, ToolCall, ToolResult) . self) { group in
211189 for (index, call) in calls. enumerated ( ) {
212190 group. addTask {
213- let result : ToolResult = if let streamableTool = self . tool ( named: call. name)
191+ let result : ToolResult = if let streamableTool = firstTool ( named: call. name, in : self . tools )
214192 as? any StreamableSubAgentTool < C > {
215193 try await self . executeStreamableWithTimeout (
216194 call, tool: streamableTool, context: context,
0 commit comments