| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { FunctionDeclaration, PartListUnion, Schema } from '@google/genai'; | |
| /** | |
| * 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; | |
| /** | |
| * Whether the tool's output should be rendered as markdown | |
| */ | |
| isOutputMarkdown: boolean; | |
| /** | |
| * Whether the tool supports live (streaming) output | |
| */ | |
| canUpdateOutput: boolean; | |
| /** | |
| * 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, | |
| abortSignal: AbortSignal, | |
| ): 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, | |
| signal: AbortSignal, | |
| updateOutput?: (output: string) => void, | |
| ): 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 isOutputMarkdown Whether the tool's output should be rendered as markdown | |
| * @param canUpdateOutput Whether the tool supports live (streaming) output | |
| * @param parameterSchema JSON Schema defining the parameters | |
| */ | |
| constructor( | |
| readonly name: string, | |
| readonly displayName: string, | |
| readonly description: string, | |
| readonly parameterSchema: Record<string, unknown>, | |
| readonly isOutputMarkdown: boolean = true, | |
| readonly canUpdateOutput: boolean = false, | |
| ) {} | |
| /** | |
| * 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, | |
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | |
| abortSignal: AbortSignal, | |
| ): 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 | |
| * @param signal AbortSignal for tool cancellation | |
| * @returns Result of the tool execution | |
| */ | |
| abstract execute( | |
| params: TParams, | |
| signal: AbortSignal, | |
| updateOutput?: (output: string) => void, | |
| ): Promise<TResult>; | |
| } | |
| export interface ToolResult { | |
| /** | |
| * Content meant to be included in LLM history. | |
| * This should represent the factual outcome of the tool execution. | |
| */ | |
| llmContent: PartListUnion; | |
| /** | |
| * 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; | |
| fileName: string; | |
| } | |
| export interface ToolEditConfirmationDetails { | |
| type: 'edit'; | |
| title: string; | |
| onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>; | |
| fileName: string; | |
| fileDiff: string; | |
| isModifying?: boolean; | |
| } | |
| export interface ToolExecuteConfirmationDetails { | |
| type: 'exec'; | |
| title: string; | |
| onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>; | |
| command: string; | |
| rootCommand: string; | |
| } | |
| export interface ToolMcpConfirmationDetails { | |
| type: 'mcp'; | |
| title: string; | |
| serverName: string; | |
| toolName: string; | |
| toolDisplayName: string; | |
| onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>; | |
| } | |
| export interface ToolInfoConfirmationDetails { | |
| type: 'info'; | |
| title: string; | |
| onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>; | |
| prompt: string; | |
| urls?: string[]; | |
| } | |
| export type ToolCallConfirmationDetails = | |
| | ToolEditConfirmationDetails | |
| | ToolExecuteConfirmationDetails | |
| | ToolMcpConfirmationDetails | |
| | ToolInfoConfirmationDetails; | |
| export enum ToolConfirmationOutcome { | |
| ProceedOnce = 'proceed_once', | |
| ProceedAlways = 'proceed_always', | |
| ProceedAlwaysServer = 'proceed_always_server', | |
| ProceedAlwaysTool = 'proceed_always_tool', | |
| ModifyWithEditor = 'modify_with_editor', | |
| Cancel = 'cancel', | |
| } | |