Tools Guide

Tool Guide

Understanding Axicov Tools

Tools are the building blocks that give your Axicov agents their capabilities. Each tool provides specific functionality that your agent can use to accomplish tasks, access data, or interact with external systems.

Tool Structure

Every tool in Axicov follows a consistent structure:

import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";
import { Agent, Tools } from "axicov-sdk";

export const myToolRegistry = async (agent: Agent) => {
  const tools: any = [];
  const schema: Tools = {};

  // 1. Define the tool schema
  schema.myToolKey = {
    name: "myToolName",
    description: "What my tool does for the agent",
    schema: z.object({
      parameter1: z.string().describe("Description of this parameter"),
      parameter2: z.number().optional().describe("Optional numeric parameter"),
    }),
    requiresApproval: false, // Whether this tool requires approval before use
  };

  // 2. Create the tool instance
  const myTool = new DynamicStructuredTool({
    name: schema.myToolKey.name,
    description: schema.myToolKey.description,
    schema: schema.myToolKey.schema,
    func: async ({ parameter1, parameter2 }) => {
      // 3. Implement the tool's functionality
      console.log(`Tool executing with: ${parameter1}, ${parameter2}`);
      
      // 4. Access agent's params or runtimeParams if needed
      const userData = agent.params.userData;
      agent.runtimeParams.lastToolUsed = "myToolName";
      
      // 5. Return the result
      return `Processed ${parameter1} successfully`;
    },
  });

  // Add the tool to the tools array
  tools.push(myTool);

  // Return both the tools array and schema
  return {
    tools,
    schema,
  };
};

Tool Registry System

Axicov uses a registry system to organize and manage tools:

Core Registry vs All Registry

When initializing an agent, you provide two types of registries:

  1. clients: The external platforms on which the agent will operate

  2. allRegistry: Additional tools that you can selectively include

await agent.initialize({
  toolNumbers: [0, 2], // Only include tools at index 0 and 2 from allRegistry
  clients: [blockchainClients],
  allRegistry: [
    weatherToolRegistry,  // index 0
    calculatorToolRegistry, // index 1
    webSearchToolRegistry, // index 2
  ],
});

Tool Selection

The toolNumbers array lets you selectively include tools from the allRegistry by their index. This allows you to create different agent configurations without modifying the registries themselves.

Creating Effective Tools

Best Practices

  1. Clear Descriptions: Write clear, concise descriptions for both tools and parameters

  2. Parameter Validation: Use Zod to validate parameter types and provide helpful error messages

  3. Error Handling: Implement proper error handling within your tool functions

  4. Logging: Include appropriate logging for debugging purposes

  5. Parameter Management: Use agent.params for persistent data and agent.runtimeParams for session data

Parameter Schema with Zod

Zod provides a powerful way to define and validate the parameters for your tools:

schema: z.object({
  // Required string parameter
  query: z.string().describe("The search query to execute"),
  
  // Optional number parameter with default
  limit: z.number().default(10).describe("Maximum number of results"),
  
  // Enum parameter for specific options
  sortBy: z.enum(["relevance", "date", "popularity"])
    .describe("How to sort the results"),
  
  // Boolean parameter
  includeImages: z.boolean().describe("Whether to include images in results"),
  
  // Nested object
  filters: z.object({
    minDate: z.string().optional().describe("Minimum date (YYYY-MM-DD)"),
    maxDate: z.string().optional().describe("Maximum date (YYYY-MM-DD)"),
  }).optional().describe("Optional filters to apply")
})

Example (Calculator Tool)

export const calculatorToolRegistry = async (agent: Agent) => {
  const tools: any = [];
  const schema: Tools = {};

  schema.calculator = {
    name: "calculate",
    description: "Perform mathematical calculations",
    schema: z.object({
      expression: z.string().describe("The mathematical expression to evaluate"),
    }),
    requiresApproval: false,
  };

  const calculatorTool = new DynamicStructuredTool({
    name: schema.calculator.name,
    description: schema.calculator.description,
    schema: schema.calculator.schema,
    func: async ({ expression }) => {
      try {
        // Simple evaluation for demonstration
        // In production, use a safe evaluation library
        const result = eval(expression);
        
        // Store calculation in runtime parameters
        if (!agent.runtimeParams.calculations) {
          agent.runtimeParams.calculations = [];
        }
        agent.runtimeParams.calculations.push({
          expression,
          result,
          timestamp: Date.now()
        });
        
        return `Result: ${result}`;
      } catch (error) {
        return "Invalid expression. Please check your input.";
      }
    },
  });

  tools.push(calculatorTool);
  return { tools, schema };
};

Next Steps

Last updated