gemini-cli/packages/server/src/tools/tools.ts

195 lines
5.5 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { FunctionDeclaration, Schema } from '@google/genai';
// Removed import for ../ui/types.js as confirmation is UI-specific
/**
* Interface representing the base Tool functionality
*/
export interface Tool<
TParams = unknown,
TResult extends ToolResult = ToolResult,
> {
/**
* The internal name of the tool (used for API calls)
*/
name: string;
/**
* The user-friendly display name of the tool
*/
displayName: string;
/**
* Description of what the tool does
*/
description: string;
/**
* Function declaration schema from @google/genai
*/
schema: FunctionDeclaration;
/**
* Validates the parameters for the tool
* Should be called from both `shouldConfirmExecute` and `execute`
* `shouldConfirmExecute` should return false immediately if invalid
* @param params Parameters to validate
* @returns An error message string if invalid, null otherwise
*/
validateToolParams(params: TParams): string | null;
/**
* Gets a pre-execution description of the tool operation
* @param params Parameters for the tool execution
* @returns A markdown string describing what the tool will do
* Optional for backward compatibility
*/
getDescription(params: TParams): string;
/**
* Determines if the tool should prompt for confirmation before execution
* @param params Parameters for the tool execution
* @returns Whether execute should be confirmed.
*/
shouldConfirmExecute(
params: TParams,
): Promise<ToolCallConfirmationDetails | false>;
/**
* Executes the tool with the given parameters
* @param params Parameters for the tool execution
* @returns Result of the tool execution
*/
execute(params: TParams): Promise<TResult>;
}
/**
* Base implementation for tools with common functionality
*/
export abstract class BaseTool<
TParams = unknown,
TResult extends ToolResult = ToolResult,
> implements Tool<TParams, TResult>
{
/**
* Creates a new instance of BaseTool
* @param name Internal name of the tool (used for API calls)
* @param displayName User-friendly display name of the tool
* @param description Description of what the tool does
* @param parameterSchema JSON Schema defining the parameters
*/
constructor(
readonly name: string,
readonly displayName: string,
readonly description: string,
readonly parameterSchema: Record<string, unknown>,
) {}
/**
* Function declaration schema computed from name, description, and parameterSchema
*/
get schema(): FunctionDeclaration {
return {
name: this.name,
description: this.description,
parameters: this.parameterSchema as Schema,
};
}
/**
* Validates the parameters for the tool
* This is a placeholder implementation and should be overridden
* Should be called from both `shouldConfirmExecute` and `execute`
* `shouldConfirmExecute` should return false immediately if invalid
* @param params Parameters to validate
* @returns An error message string if invalid, null otherwise
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
validateToolParams(params: TParams): string | null {
// Implementation would typically use a JSON Schema validator
// This is a placeholder that should be implemented by derived classes
return null;
}
/**
* Gets a pre-execution description of the tool operation
* Default implementation that should be overridden by derived classes
* @param params Parameters for the tool execution
* @returns A markdown string describing what the tool will do
*/
getDescription(params: TParams): string {
return JSON.stringify(params);
}
/**
* Determines if the tool should prompt for confirmation before execution
* @param params Parameters for the tool execution
* @returns Whether or not execute should be confirmed by the user.
*/
shouldConfirmExecute(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
params: TParams,
): Promise<ToolCallConfirmationDetails | false> {
return Promise.resolve(false);
}
/**
* Abstract method to execute the tool with the given parameters
* Must be implemented by derived classes
* @param params Parameters for the tool execution
* @returns Result of the tool execution
*/
abstract execute(params: TParams): Promise<TResult>;
}
export interface ToolResult {
/**
* Content meant to be included in LLM history.
* This should represent the factual outcome of the tool execution.
*/
llmContent: string;
/**
* Markdown string for user display.
* This provides a user-friendly summary or visualization of the result.
* NOTE: This might also be considered UI-specific and could potentially be
* removed or modified in a further refactor if the server becomes purely API-driven.
* For now, we keep it as the core logic in ReadFileTool currently produces it.
*/
returnDisplay: ToolResultDisplay;
}
export type ToolResultDisplay = string | FileDiff;
export interface FileDiff {
fileDiff: string;
}
export interface ToolCallConfirmationDetails {
title: string;
onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>;
}
export interface ToolEditConfirmationDetails
extends ToolCallConfirmationDetails {
fileName: string;
fileDiff: string;
}
export interface ToolExecuteConfirmationDetails
extends ToolCallConfirmationDetails {
command: string;
rootCommand: string;
}
export enum ToolConfirmationOutcome {
ProceedOnce,
ProceedAlways,
Cancel,
}