/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type { AnyDeclarativeTool, AnyToolInvocation } from '../index.js'; import { isTool } from '../index.js'; import { SHELL_TOOL_NAMES } from './shell-utils.js'; /** * Checks if a tool invocation matches any of a list of patterns. * * @param toolOrToolName The tool object or the name of the tool being invoked. * @param invocation The invocation object for the tool or the command invoked. * @param patterns A list of patterns to match against. * Patterns can be: * - A tool name (e.g., "ReadFileTool") to match any invocation of that tool. * - A tool name with a prefix (e.g., "ShellTool(git status)") to match * invocations where the arguments start with that prefix. * @returns True if the invocation matches any pattern, false otherwise. */ export function doesToolInvocationMatch( toolOrToolName: AnyDeclarativeTool | string, invocation: AnyToolInvocation | string, patterns: string[], ): boolean { let toolNames: string[]; if (isTool(toolOrToolName)) { toolNames = [toolOrToolName.name, toolOrToolName.constructor.name]; } else { toolNames = [toolOrToolName as string]; } if (toolNames.some((name) => SHELL_TOOL_NAMES.includes(name))) { toolNames = [...new Set([...toolNames, ...SHELL_TOOL_NAMES])]; } for (const pattern of patterns) { const openParen = pattern.indexOf('('); if (openParen === -1) { // No arguments, just a tool name if (toolNames.includes(pattern)) { return true; } continue; } const patternToolName = pattern.substring(0, openParen); if (!toolNames.includes(patternToolName)) { continue; } if (!pattern.endsWith(')')) { continue; } const argPattern = pattern.substring(openParen + 1, pattern.length - 1); let command: string; if (typeof invocation === 'string') { command = invocation; } else { if (!('command' in invocation.params)) { // This invocation has no command - nothing to check. continue; } command = String((invocation.params as { command: string }).command); } if (toolNames.some((name) => SHELL_TOOL_NAMES.includes(name))) { if (command === argPattern || command.startsWith(argPattern + ' ')) { return true; } } } return false; }