Add and improve JSDoc comments for core tool methods (#3128)

This commit is contained in:
moon jooho 2025-07-04 09:13:02 +09:00 committed by GitHub
parent 654f8aeb61
commit 8d3fec08e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 55 additions and 6 deletions

View File

@ -134,7 +134,7 @@ To start the Gemini CLI from the source code (after building), run the following
npm start npm start
``` ```
If youd like to run the source build outside of the gemini-cli folder you can utilize `npm link path/to/gemini-cli/packages/cli` (see: [docs](https://docs.npmjs.com/cli/v9/commands/npm-link)) or `alias gemini="node path/to/gemini-cli/packages/cli"` to run with `gemini` If you'd like to run the source build outside of the gemini-cli folder you can utilize `npm link path/to/gemini-cli/packages/cli` (see: [docs](https://docs.npmjs.com/cli/v9/commands/npm-link)) or `alias gemini="node path/to/gemini-cli/packages/cli"` to run with `gemini`
### Running Tests ### Running Tests

View File

@ -560,8 +560,8 @@ describe('useReactToolScheduler', () => {
(mockToolWithLiveOutput.execute as Mock).mockImplementation( (mockToolWithLiveOutput.execute as Mock).mockImplementation(
async ( async (
_args: any, _args: Record<string, unknown>,
_signal: any, _signal: AbortSignal,
updateFn: ((output: string) => void) | undefined, updateFn: ((output: string) => void) | undefined,
) => { ) => {
liveUpdateFn = updateFn; liveUpdateFn = updateFn;

View File

@ -122,7 +122,11 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
} }
/** /**
* Checks if a path is within the root directory. * Checks if a given path is within the root directory bounds.
* This security check prevents accessing files outside the designated root directory.
*
* @param pathToCheck The absolute path to validate
* @returns True if the path is within the root directory, false otherwise
*/ */
private isWithinRoot(pathToCheck: string): boolean { private isWithinRoot(pathToCheck: string): boolean {
const absolutePathToCheck = path.resolve(pathToCheck); const absolutePathToCheck = path.resolve(pathToCheck);

View File

@ -162,6 +162,16 @@ export async function discoverMcpTools(
} }
} }
/**
* Connects to an MCP server and discovers available tools, registering them with the tool registry.
* This function handles the complete lifecycle of connecting to a server, discovering tools,
* and cleaning up resources if no tools are found.
*
* @param mcpServerName The name identifier for this MCP server
* @param mcpServerConfig Configuration object containing connection details
* @param toolRegistry The registry to register discovered tools with
* @returns Promise that resolves when discovery is complete
*/
async function connectAndDiscover( async function connectAndDiscover(
mcpServerName: string, mcpServerName: string,
mcpServerConfig: MCPServerConfig, mcpServerConfig: MCPServerConfig,
@ -375,6 +385,13 @@ async function connectAndDiscover(
} }
} }
/**
* Sanitizes a JSON schema object to ensure compatibility with Vertex AI.
* This function recursively processes the schema to remove problematic properties
* that can cause issues with the Gemini API.
*
* @param schema The JSON schema object to sanitize (modified in-place)
*/
export function sanitizeParameters(schema?: Schema) { export function sanitizeParameters(schema?: Schema) {
if (!schema) { if (!schema) {
return; return;

View File

@ -89,6 +89,15 @@ Process Group PGID: Process group started or \`(none)\``,
return description; return description;
} }
/**
* Extracts the root command from a given shell command string.
* This is used to identify the base command for permission checks.
*
* @param command The shell command string to parse
* @returns The root command name, or undefined if it cannot be determined
* @example getCommandRoot("ls -la /tmp") returns "ls"
* @example getCommandRoot("git status && npm test") returns "git"
*/
getCommandRoot(command: string): string | undefined { getCommandRoot(command: string): string | undefined {
return command return command
.trim() // remove leading and trailing whitespace .trim() // remove leading and trailing whitespace
@ -98,6 +107,13 @@ Process Group PGID: Process group started or \`(none)\``,
.pop(); // take last part and return command root (or undefined if previous line was empty) .pop(); // take last part and return command root (or undefined if previous line was empty)
} }
/**
* Determines whether a given shell command is allowed to execute based on
* the tool's configuration including allowlists and blocklists.
*
* @param command The shell command string to validate
* @returns True if the command is allowed to execute, false otherwise
*/
isCommandAllowed(command: string): boolean { isCommandAllowed(command: string): boolean {
// 0. Disallow command substitution // 0. Disallow command substitution
if (command.includes('$(') || command.includes('`')) { if (command.includes('$(') || command.includes('`')) {

View File

@ -81,7 +81,12 @@ export class WebSearchTool extends BaseTool<
); );
} }
validateParams(params: WebSearchToolParams): string | null { /**
* Validates the parameters for the WebSearchTool.
* @param params The parameters to validate
* @returns An error message string if validation fails, null if valid
*/
validateToolParams(params: WebSearchToolParams): string | null {
if ( if (
this.schema.parameters && this.schema.parameters &&
!SchemaValidator.validate( !SchemaValidator.validate(
@ -105,7 +110,7 @@ export class WebSearchTool extends BaseTool<
params: WebSearchToolParams, params: WebSearchToolParams,
signal: AbortSignal, signal: AbortSignal,
): Promise<WebSearchToolResult> { ): Promise<WebSearchToolResult> {
const validationError = this.validateParams(params); const validationError = this.validateToolParams(params);
if (validationError) { if (validationError) {
return { return {
llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`, llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,

View File

@ -96,6 +96,13 @@ export class WriteFileTool
this.client = this.config.getGeminiClient(); this.client = this.config.getGeminiClient();
} }
/**
* Checks if a given path is within the root directory bounds.
* This security check prevents writing files outside the designated root directory.
*
* @param pathToCheck The absolute path to validate
* @returns True if the path is within the root directory, false otherwise
*/
private isWithinRoot(pathToCheck: string): boolean { private isWithinRoot(pathToCheck: string): boolean {
const normalizedPath = path.normalize(pathToCheck); const normalizedPath = path.normalize(pathToCheck);
const normalizedRoot = path.normalize(this.config.getTargetDir()); const normalizedRoot = path.normalize(this.config.getTargetDir());