(
agentDefinition: Pick<
AgentDefinition,
'tools' | 'disallowedTools' | 'source' | 'permissionMode'
>,
availableTools: Tools,
isAsync = false,
isMainThread = false,
)
| 120 | * Handles wildcard expansion and validation in one place |
| 121 | */ |
| 122 | export function resolveAgentTools( |
| 123 | agentDefinition: Pick< |
| 124 | AgentDefinition, |
| 125 | 'tools' | 'disallowedTools' | 'source' | 'permissionMode' |
| 126 | >, |
| 127 | availableTools: Tools, |
| 128 | isAsync = false, |
| 129 | isMainThread = false, |
| 130 | ): ResolvedAgentTools { |
| 131 | const { |
| 132 | tools: agentTools, |
| 133 | disallowedTools, |
| 134 | source, |
| 135 | permissionMode, |
| 136 | } = agentDefinition |
| 137 | // When isMainThread is true, skip filterToolsForAgent entirely — the main |
| 138 | // thread's tool pool is already properly assembled by useMergedTools(), so |
| 139 | // the sub-agent disallow lists shouldn't apply. |
| 140 | const filteredAvailableTools = isMainThread |
| 141 | ? availableTools |
| 142 | : filterToolsForAgent({ |
| 143 | tools: availableTools, |
| 144 | isBuiltIn: source === 'built-in', |
| 145 | isAsync, |
| 146 | permissionMode, |
| 147 | }) |
| 148 | |
| 149 | // Create a set of disallowed tool names for quick lookup |
| 150 | const disallowedToolSet = new Set( |
| 151 | disallowedTools?.map(toolSpec => { |
| 152 | const { toolName } = permissionRuleValueFromString(toolSpec) |
| 153 | return toolName |
| 154 | }) ?? [], |
| 155 | ) |
| 156 | |
| 157 | // Filter available tools based on disallowed list |
| 158 | const allowedAvailableTools = filteredAvailableTools.filter( |
| 159 | tool => !disallowedToolSet.has(tool.name), |
| 160 | ) |
| 161 | |
| 162 | // If tools is undefined or ['*'], allow all tools (after filtering disallowed) |
| 163 | const hasWildcard = |
| 164 | agentTools === undefined || |
| 165 | (agentTools.length === 1 && agentTools[0] === '*') |
| 166 | if (hasWildcard) { |
| 167 | return { |
| 168 | hasWildcard: true, |
| 169 | validTools: [], |
| 170 | invalidTools: [], |
| 171 | resolvedTools: allowedAvailableTools, |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | const availableToolMap = new Map<string, Tool>() |
| 176 | for (const tool of allowedAvailableTools) { |
| 177 | availableToolMap.set(tool.name, tool) |
| 178 | } |
| 179 |
no test coverage detected