/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type { ToolCallConfirmationDetails, ToolInvocation, ToolResult, } from '../tools/tools.js'; import { BaseDeclarativeTool, BaseToolInvocation, Kind, } from '../tools/tools.js'; interface MockToolOptions { name: string; displayName?: string; description?: string; canUpdateOutput?: boolean; isOutputMarkdown?: boolean; shouldConfirmExecute?: ( params: { [key: string]: unknown }, signal: AbortSignal, ) => Promise; execute?: ( params: { [key: string]: unknown }, signal: AbortSignal, updateOutput?: (output: string) => void, ) => Promise; params?: object; } class MockToolInvocation extends BaseToolInvocation< { [key: string]: unknown }, ToolResult > { constructor( private readonly tool: MockTool, params: { [key: string]: unknown }, ) { super(params); } execute( signal: AbortSignal, updateOutput?: (output: string) => void, ): Promise { return this.tool.execute(this.params, signal, updateOutput); } override shouldConfirmExecute( abortSignal: AbortSignal, ): Promise { return this.tool.shouldConfirmExecute(this.params, abortSignal); } getDescription(): string { return `A mock tool invocation for ${this.tool.name}`; } } /** * A highly configurable mock tool for testing purposes. */ export class MockTool extends BaseDeclarativeTool< { [key: string]: unknown }, ToolResult > { shouldConfirmExecute: ( params: { [key: string]: unknown }, signal: AbortSignal, ) => Promise; execute: ( params: { [key: string]: unknown }, signal: AbortSignal, updateOutput?: (output: string) => void, ) => Promise; constructor(options: MockToolOptions) { super( options.name, options.displayName ?? options.name, options.description ?? options.name, Kind.Other, options.params, options.isOutputMarkdown ?? false, options.canUpdateOutput ?? false, ); if (options.shouldConfirmExecute) { this.shouldConfirmExecute = options.shouldConfirmExecute; } else { this.shouldConfirmExecute = () => Promise.resolve(false); } if (options.execute) { this.execute = options.execute; } else { this.execute = () => Promise.resolve({ llmContent: `Tool ${this.name} executed successfully.`, returnDisplay: `Tool ${this.name} executed successfully.`, }); } } protected createInvocation(params: { [key: string]: unknown; }): ToolInvocation<{ [key: string]: unknown }, ToolResult> { return new MockToolInvocation(this, params); } }