Skip to main content

Overview

BaseTool is the abstract base class that all tools in ADK-TS must extend. It provides core functionality for tool execution, validation, error handling, retry logic, and integration with LLM requests.

Constructor

constructor(config: ToolConfig)
Creates a new tool instance with the specified configuration.

Parameters

config
ToolConfig
required
Configuration object for the tool

Properties

name
string
Name of the tool as specified in the constructor.
description
string
Description of the tool as specified in the constructor.
isLongRunning
boolean
Whether this is a long-running operation.
shouldRetryOnFailure
boolean
Whether to retry execution on failure.
maxRetryAttempts
number
Maximum number of retry attempts.
baseRetryDelay
number
default:"1000"
Base delay for retry in milliseconds (used with exponential backoff).
maxRetryDelay
number
default:"10000"
Maximum delay for retry in milliseconds.

Methods

getDeclaration()

getDeclaration(): FunctionDeclaration | null
Returns the OpenAPI specification of this tool as a FunctionDeclaration. This is used to tell the LLM what parameters the tool accepts.
Required if your tool uses the default implementation of processLlmRequest. Can return null for built-in tools that don’t need to be added to LLM requests.
return
FunctionDeclaration | null
The function declaration for this tool, or null if not needed.

runAsync()

async runAsync(
  args: Record<string, any>,
  context: ToolContext
): Promise<any>
Executes the tool with the given arguments and context. This is the main method you need to implement when creating a custom tool.
args
Record<string, any>
required
The LLM-filled arguments for this tool execution.
context
ToolContext
required
The execution context containing session, memory, and other services. See ToolContext for details.
return
any
The result of running the tool. Should typically be an object.

validateArguments()

validateArguments(args: Record<string, any>): boolean
Validates the arguments against the schema defined in the function declaration.
args
Record<string, any>
required
Arguments to validate.
return
boolean
true if arguments are valid, false otherwise.

safeExecute()

async safeExecute(
  args: Record<string, any>,
  context: ToolContext
): Promise<any>
Executes the tool with error handling and automatic retries if configured. This method:
  • Validates arguments before execution
  • Handles errors gracefully
  • Implements exponential backoff retry logic
  • Returns structured error responses on failure
args
Record<string, any>
required
Arguments for the tool.
context
ToolContext
required
Tool execution context.
return
object
Either { result: any } on success or { error: string, message: string, tool: string } on failure.

processLlmRequest()

async processLlmRequest(
  toolContext: ToolContext,
  llmRequest: LlmRequest
): Promise<void>
Processes the outgoing LLM request for this tool. The default implementation adds this tool’s function declaration to the LLM request. Override this method for custom preprocessing logic.
toolContext
ToolContext
required
The context of the tool.
llmRequest
LlmRequest
required
The outgoing LLM request, which can be mutated by this method.

Example Implementation

Here’s a complete example of a custom tool extending BaseTool:
import { BaseTool, ToolContext } from '@iqai/adk';
import { Type } from '@google/genai';
import type { FunctionDeclaration } from '@iqai/adk';

export class HttpRequestTool extends BaseTool {
  constructor() {
    super({
      name: 'http_request',
      description: 'Make HTTP requests to external APIs and web services',
      shouldRetryOnFailure: true,
      maxRetryAttempts: 3
    });
  }

  getDeclaration(): FunctionDeclaration {
    return {
      name: this.name,
      description: this.description,
      parameters: {
        type: Type.OBJECT,
        properties: {
          url: {
            type: Type.STRING,
            description: 'The URL to send the request to'
          },
          method: {
            type: Type.STRING,
            description: 'The HTTP method (GET, POST, etc.)',
            enum: ['GET', 'POST', 'PUT', 'DELETE'],
            default: 'GET'
          },
          headers: {
            type: Type.OBJECT,
            description: 'Request headers to include'
          },
          body: {
            type: Type.STRING,
            description: 'Request body content'
          }
        },
        required: ['url']
      }
    };
  }

  async runAsync(
    args: {
      url: string;
      method?: string;
      headers?: Record<string, string>;
      body?: string;
    },
    _context: ToolContext
  ): Promise<any> {
    const { url, method = 'GET', headers = {}, body } = args;

    try {
      const response = await fetch(url, {
        method,
        headers,
        body
      });

      const responseBody = await response.text();

      return {
        statusCode: response.status,
        body: responseBody,
        headers: Object.fromEntries(response.headers.entries())
      };
    } catch (error) {
      return {
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }
}

See Also

Build docs developers (and LLMs) love