mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 23:51:16 -07:00
refactor: centralize all tool definitions in coreTools.ts
This commit is contained in:
@@ -7,7 +7,41 @@
|
||||
import { Type } from '@google/genai';
|
||||
import type { ToolDefinition } from './types.js';
|
||||
import { READ_FILE_TOOL_NAME, SHELL_TOOL_NAME } from '../tool-names.js';
|
||||
import { getCommandDescription } from '../shell.js';
|
||||
import * as os from 'node:os';
|
||||
|
||||
export function getShellToolDescription(
|
||||
enableInteractiveShell: boolean,
|
||||
): string {
|
||||
const returnedInfo = `
|
||||
|
||||
The following information is returned:
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available.`;
|
||||
|
||||
if (os.platform() === 'win32') {
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use PowerShell background constructs.'
|
||||
: 'Command can start background processes using PowerShell constructs such as `Start-Process -NoNewWindow` or `Start-Job`.';
|
||||
return `This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`. ${backgroundInstructions}${returnedInfo}`;
|
||||
} else {
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use `&` to background commands.'
|
||||
: 'Command can start background processes using `&`.';
|
||||
return `This tool executes a given shell command as \`bash -c <command>\`. ${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${returnedInfo}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function getCommandDescription(): string {
|
||||
if (os.platform() === 'win32') {
|
||||
return 'Exact command to execute as `powershell.exe -NoProfile -Command <command>`';
|
||||
}
|
||||
return 'Exact bash command to execute as `bash -c <command>`';
|
||||
}
|
||||
|
||||
export const READ_FILE_DEFINITION: ToolDefinition = {
|
||||
base: {
|
||||
@@ -36,34 +70,38 @@ export const READ_FILE_DEFINITION: ToolDefinition = {
|
||||
},
|
||||
};
|
||||
|
||||
export const SHELL_DEFINITION: ToolDefinition = {
|
||||
base: {
|
||||
name: SHELL_TOOL_NAME,
|
||||
description: 'Executes a shell command.',
|
||||
parameters: {
|
||||
type: Type.OBJECT,
|
||||
properties: {
|
||||
command: {
|
||||
type: Type.STRING,
|
||||
description: getCommandDescription(),
|
||||
},
|
||||
description: {
|
||||
type: Type.STRING,
|
||||
description:
|
||||
'Brief description of the command for the user. Be specific and concise. Ideally a single sentence. Can be up to 3 sentences for clarity. No line breaks.',
|
||||
},
|
||||
dir_path: {
|
||||
type: Type.STRING,
|
||||
description:
|
||||
'(OPTIONAL) The path of the directory to run the command in. If not provided, the project root directory is used. Must be a directory within the workspace and must already exist.',
|
||||
},
|
||||
is_background: {
|
||||
type: Type.BOOLEAN,
|
||||
description:
|
||||
'Set to true if this command should be run in the background (e.g. for long-running servers or watchers). The command will be started, allowed to run for a brief moment to check for immediate errors, and then moved to the background.',
|
||||
export function getShellDefinition(
|
||||
enableInteractiveShell: boolean,
|
||||
): ToolDefinition {
|
||||
return {
|
||||
base: {
|
||||
name: SHELL_TOOL_NAME,
|
||||
description: getShellToolDescription(enableInteractiveShell),
|
||||
parameters: {
|
||||
type: Type.OBJECT,
|
||||
properties: {
|
||||
command: {
|
||||
type: Type.STRING,
|
||||
description: getCommandDescription(),
|
||||
},
|
||||
description: {
|
||||
type: Type.STRING,
|
||||
description:
|
||||
'Brief description of the command for the user. Be specific and concise. Ideally a single sentence. Can be up to 3 sentences for clarity. No line breaks.',
|
||||
},
|
||||
dir_path: {
|
||||
type: Type.STRING,
|
||||
description:
|
||||
'(OPTIONAL) The path of the directory to run the command in. If not provided, the project root directory is used. Must be a directory within the workspace and must already exist.',
|
||||
},
|
||||
is_background: {
|
||||
type: Type.BOOLEAN,
|
||||
description:
|
||||
'Set to true if this command should be run in the background (e.g. for long-running servers or watchers). The command will be started, allowed to run for a brief moment to check for immediate errors, and then moved to the background.',
|
||||
},
|
||||
},
|
||||
required: ['command'],
|
||||
},
|
||||
required: ['command'],
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import {
|
||||
} from '../utils/shell-utils.js';
|
||||
import { SHELL_TOOL_NAME } from './tool-names.js';
|
||||
import type { MessageBus } from '../confirmation-bus/message-bus.js';
|
||||
import { SHELL_DEFINITION } from './definitions/coreTools.js';
|
||||
import { getShellDefinition } from './definitions/coreTools.js';
|
||||
import { resolveToolDeclaration } from './definitions/resolver.js';
|
||||
|
||||
export const OUTPUT_UPDATE_INTERVAL_MS = 1000;
|
||||
@@ -453,41 +453,6 @@ export class ShellToolInvocation extends BaseToolInvocation<
|
||||
}
|
||||
}
|
||||
|
||||
export function getShellToolDescription(
|
||||
enableInteractiveShell: boolean,
|
||||
): string {
|
||||
const returnedInfo = `
|
||||
|
||||
The following information is returned:
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available.`;
|
||||
|
||||
if (os.platform() === 'win32') {
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use PowerShell background constructs.'
|
||||
: 'Command can start background processes using PowerShell constructs such as `Start-Process -NoNewWindow` or `Start-Job`.';
|
||||
return `This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`. ${backgroundInstructions}${returnedInfo}`;
|
||||
} else {
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use `&` to background commands.'
|
||||
: 'Command can start background processes using `&`.';
|
||||
return `This tool executes a given shell command as \`bash -c <command>\`. ${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${returnedInfo}`;
|
||||
}
|
||||
}
|
||||
|
||||
export function getCommandDescription(): string {
|
||||
if (os.platform() === 'win32') {
|
||||
return 'Exact command to execute as `powershell.exe -NoProfile -Command <command>`';
|
||||
} else {
|
||||
return 'Exact bash command to execute as `bash -c <command>`';
|
||||
}
|
||||
}
|
||||
|
||||
export class ShellTool extends BaseDeclarativeTool<
|
||||
ShellToolParams,
|
||||
ToolResult
|
||||
@@ -501,12 +466,13 @@ export class ShellTool extends BaseDeclarativeTool<
|
||||
void initializeShellParsers().catch(() => {
|
||||
// Errors are surfaced when parsing commands.
|
||||
});
|
||||
const definition = getShellDefinition(config.getEnableInteractiveShell());
|
||||
super(
|
||||
ShellTool.Name,
|
||||
'Shell',
|
||||
getShellToolDescription(config.getEnableInteractiveShell()),
|
||||
definition.base.description!,
|
||||
Kind.Execute,
|
||||
SHELL_DEFINITION.base.parameters!,
|
||||
definition.base.parameters!,
|
||||
messageBus,
|
||||
false, // output is not markdown
|
||||
true, // output can be updated
|
||||
@@ -546,18 +512,13 @@ export class ShellTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
const definition = getShellDefinition(
|
||||
this.config.getEnableInteractiveShell(),
|
||||
);
|
||||
if (!modelId) {
|
||||
return super.getSchema();
|
||||
}
|
||||
|
||||
const declaration = resolveToolDeclaration(SHELL_DEFINITION, modelId);
|
||||
const schema = super.getSchema();
|
||||
|
||||
// We use the resolved declaration but preserve the dynamic platform-specific description
|
||||
// from the tool instance to ensure behavior remains 100% identical for now.
|
||||
return {
|
||||
...declaration,
|
||||
description: schema.description,
|
||||
};
|
||||
return resolveToolDeclaration(definition, modelId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user