summaryrefslogtreecommitdiff
path: root/packages/cli/src/tools/web-fetch.tool.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/tools/web-fetch.tool.ts')
-rw-r--r--packages/cli/src/tools/web-fetch.tool.ts162
1 files changed, 27 insertions, 135 deletions
diff --git a/packages/cli/src/tools/web-fetch.tool.ts b/packages/cli/src/tools/web-fetch.tool.ts
index cd5e01e8..b543dd90 100644
--- a/packages/cli/src/tools/web-fetch.tool.ts
+++ b/packages/cli/src/tools/web-fetch.tool.ts
@@ -4,169 +4,61 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { SchemaValidator } from '../utils/schemaValidator.js';
-import { BaseTool, ToolResult } from './tools.js';
-import { ToolCallConfirmationDetails } from '../ui/types.js'; // Added for shouldConfirmExecute
-import { getErrorMessage } from '../utils/errors.js';
+// Import core logic and types from the server package
+import {
+ WebFetchLogic,
+ WebFetchToolParams,
+ ToolResult,
+} from '@gemini-code/server';
-/**
- * Parameters for the WebFetch tool
- */
-export interface WebFetchToolParams {
- /**
- * The URL to fetch content from.
- */
- url: string;
-}
+// Import CLI-specific base class and UI types
+import { BaseTool } from './tools.js';
+import { ToolCallConfirmationDetails } from '../ui/types.js';
/**
- * Implementation of the WebFetch tool that reads content from a URL.
+ * CLI wrapper for the WebFetch tool.
*/
export class WebFetchTool extends BaseTool<WebFetchToolParams, ToolResult> {
- static readonly Name: string = 'web_fetch';
+ static readonly Name: string = WebFetchLogic.Name; // Use name from logic
+
+ // Core logic instance from the server package
+ private coreLogic: WebFetchLogic;
- /**
- * Creates a new instance of the WebFetchTool
- */
constructor() {
+ const coreLogicInstance = new WebFetchLogic();
super(
WebFetchTool.Name,
- 'WebFetch',
- 'Fetches text content from a given URL. Handles potential network errors and non-success HTTP status codes.',
- {
- properties: {
- url: {
- description:
- "The URL to fetch. Must be an absolute URL (e.g., 'https://example.com/file.txt').",
- type: 'string',
- },
- },
- required: ['url'],
- type: 'object',
- },
+ 'WebFetch', // Define display name here
+ 'Fetches text content from a given URL. Handles potential network errors and non-success HTTP status codes.', // Define description here
+ (coreLogicInstance.schema.parameters as Record<string, unknown>) ?? {},
);
- // No rootDirectory needed for web fetching
+ this.coreLogic = coreLogicInstance;
}
- /**
- * Validates the parameters for the WebFetch tool
- * @param params Parameters to validate
- * @returns An error message string if invalid, null otherwise
- */
- invalidParams(params: WebFetchToolParams): string | null {
- // 1. Validate against the basic schema first
- if (
- this.schema.parameters &&
- !SchemaValidator.validate(
- this.schema.parameters as Record<string, unknown>,
- params,
- )
- ) {
- return 'Parameters failed schema validation.';
- }
-
- // 2. Validate the URL format and protocol
- try {
- const parsedUrl = new URL(params.url);
- // Ensure it's an HTTP or HTTPS URL
- if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
- return `Invalid URL protocol: "${parsedUrl.protocol}". Only 'http:' and 'https:' are supported.`;
- }
- } catch {
- // The URL constructor throws if the format is invalid
- return `Invalid URL format: "${params.url}". Please provide a valid absolute URL (e.g., 'https://example.com').`;
- }
-
- // If all checks pass, the parameters are valid
- return null;
+ validateToolParams(params: WebFetchToolParams): string | null {
+ // Delegate validation to core logic
+ return this.coreLogic.validateParams(params);
}
- /**
- * Gets a description of the web fetch operation.
- * @param params Parameters for the web fetch.
- * @returns A string describing the operation.
- */
getDescription(params: WebFetchToolParams): string {
- // Shorten long URLs for display
- const displayUrl =
- params.url.length > 80 ? params.url.substring(0, 77) + '...' : params.url;
- return `Fetching content from ${displayUrl}`;
+ // Delegate description generation to core logic
+ return this.coreLogic.getDescription(params);
}
/**
- * Determines if the tool should prompt for confirmation before execution.
- * Web fetches are generally safe, so default to false.
- * @param params Parameters for the tool execution
- * @returns Whether execute should be confirmed.
+ * Define confirmation behavior (WebFetch likely doesn't need confirmation)
*/
async shouldConfirmExecute(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
params: WebFetchToolParams,
): Promise<ToolCallConfirmationDetails | false> {
- // Could add logic here to confirm based on domain, etc. if needed
return Promise.resolve(false);
}
/**
- * Fetches content from the specified URL.
- * @param params Parameters for the web fetch operation.
- * @returns Result with the fetched content or an error message.
+ * Delegates execution to the core logic.
*/
async execute(params: WebFetchToolParams): Promise<ToolResult> {
- const validationError = this.invalidParams(params);
- if (validationError) {
- return {
- llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
- returnDisplay: `**Error:** Invalid parameters. ${validationError}`,
- };
- }
-
- const url = params.url;
-
- try {
- const response = await fetch(url, {
- headers: {
- 'User-Agent': 'GeminiCode-CLI/1.0',
- },
- signal: AbortSignal.timeout(15000), // 15 seconds timeout
- });
-
- if (!response.ok) {
- // fetch doesn't throw on bad HTTP status codes (4xx, 5xx)
- const errorText = `Failed to fetch data from ${url}. Status: ${response.status} ${response.statusText}`;
- return {
- llmContent: `Error: ${errorText}`,
- returnDisplay: `**Error:** ${errorText}`,
- };
- }
-
- // Assuming the response is text. Add checks for content-type if needed.
- const data = await response.text();
- let llmContent = '';
- // Truncate very large responses for the LLM context
- const MAX_LLM_CONTENT_LENGTH = 200000;
- if (data) {
- llmContent = `Fetched data from ${url}:\n\n${
- data.length > MAX_LLM_CONTENT_LENGTH
- ? data.substring(0, MAX_LLM_CONTENT_LENGTH) +
- '\n... [Content truncated]'
- : data
- }`;
- } else {
- llmContent = `No data fetched from ${url}. Status: ${response.status}`;
- }
- return {
- llmContent,
- returnDisplay: `Fetched content from ${url}`, // Simple display message
- };
- } catch (error: unknown) {
- // This catches network errors (DNS resolution, connection refused, etc.)
- // and errors from the URL constructor if somehow bypassed validation (unlikely)
- const errorMessage = `Failed to fetch data from ${url}. Error: ${getErrorMessage(error)}`;
- return {
- llmContent: `Error: ${errorMessage}`,
- returnDisplay: `**Error:** ${errorMessage}`,
- };
- }
+ return this.coreLogic.execute(params);
}
}