Plugin

Extensible tool system with JSON schema validation and automatic function calling

Overview#

Plugins extend agent capabilities by providing tools that can be called during conversations. The plugin system is built around a decorator pattern that enhances agents with tool execution capabilities. It provides automatic parameter validation, error handling, and seamless LLM integration with function calling.

Built-in Tools#

Astreus comes with several built-in tools available to all agents:

Knowledge Tools#

  • search_knowledge: Search through the agent's knowledge base for relevant information
    • query (string, required): Search query
    • limit (number, optional): Maximum results (default: 5)
    • threshold (number, optional): Similarity threshold (default: 0.7)

Vision Tools#

  • analyze_image: General image analysis with custom prompts
  • describe_image: Generate accessibility-friendly descriptions
  • extract_text_from_image: OCR capabilities for text extraction

Creating Custom Plugins#

Define Your Tool#

Create a tool definition with handler function:

typescript
import { ToolDefinition, ToolContext, ToolParameterValue } from '@astreus-ai/astreus';

const weatherTool: ToolDefinition = {
  name: 'get_weather',
  description: 'Get current weather information for a location',
  parameters: {
    location: {
      name: 'location',
      type: 'string',
      description: 'City name or location',
      required: true
    },
    units: {
      name: 'units',
      type: 'string',
      description: 'Temperature units (celsius or fahrenheit)',
      required: false
    }
  },
  handler: async (params: Record<string, ToolParameterValue>, context?: ToolContext) => {
    try {
      // Your tool implementation
      const weather = await fetchWeather(params.location as string, params.units as string);

      return {
        success: true,
        data: {
          temperature: weather.temp,
          conditions: weather.conditions,
          location: params.location
        }
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }
};

Create the Plugin#

Bundle your tools into a plugin:

typescript
import { Plugin, ToolParameterValue } from '@astreus-ai/astreus';

const weatherPlugin: Plugin = {
  name: 'weather-plugin',
  version: '1.0.0',
  description: 'Weather information tools',
  tools: [weatherTool],
  
  // Optional: Plugin initialization
  initialize: async (config?: Record<string, ToolParameterValue>) => {
    console.log('Weather plugin initialized');
  },
  
  // Optional: Plugin cleanup
  cleanup: async () => {
    console.log('Weather plugin cleaned up');
  }
};

Register with Agent#

Register your plugin with an agent:

typescript
import { Agent } from '@astreus-ai/astreus';

const agent = await Agent.create({
  name: 'WeatherAgent',
  model: 'gpt-4o'
});

// Register the plugin
await agent.registerPlugin(weatherPlugin);

Tool Parameter Types#

The plugin system supports comprehensive parameter validation:

typescript
// Parameter type definitions
interface ToolParameter {
  name: string;              // Parameter name
  type: 'string' | 'number' | 'boolean' | 'object' | 'array';
  description: string;       // Parameter description
  required?: boolean;        // Whether parameter is required (optional, defaults to false)
  enum?: Array<string | number>;  // Allowed values (supports both string and number)
  properties?: Record<string, ToolParameter>; // For object types (nested properties)
  items?: ToolParameter;     // For array types (item type definition)
}

Parameter Examples#

typescript
const advancedTool: ToolDefinition = {
  name: 'process_data',
  description: 'Process data with various options',
  parameters: {
    // String with enum values
    format: {
      name: 'format',
      type: 'string',
      description: 'Output format',
      required: true,
      enum: ['json', 'csv', 'xml']
    },
    
    // Number parameter (optional)
    limit: {
      name: 'limit',
      type: 'number',
      description: 'Maximum records to process',
      required: false
    },
    
    // Object with nested properties
    options: {
      name: 'options',
      type: 'object',
      description: 'Processing options',
      required: false,
      properties: {
        includeHeaders: {
          name: 'includeHeaders',
          type: 'boolean',
          description: 'Include column headers',
          required: false
        }
      }
    },
    
    // Array of strings
    fields: {
      name: 'fields',
      type: 'array',
      description: 'Fields to include',
      required: false,
      items: {
        name: 'field',
        type: 'string',
        description: 'Field name'
      }
    }
  },
  handler: async (params) => {
    // Tool implementation
    return { success: true, data: params };
  }
};

Using Tools in Conversations#

Automatic Tool Usage#

Agents with registered plugins can automatically use tools during conversations:

typescript
const agent = await Agent.create({
  name: 'AssistantAgent',
  model: 'gpt-4o'
});

await agent.registerPlugin(weatherPlugin);

// Agent can automatically call tools based on conversation
const response = await agent.ask("What's the weather like in Tokyo?");
// Agent will automatically call get_weather tool and incorporate results

console.log(response);
// "The current weather in Tokyo is 22°C with clear skies..."

Manual Tool Execution#

You can also execute tools manually:

typescript
// Execute single tool
const result = await agent.executeTool({
  id: 'call-123',
  name: 'get_weather',
  parameters: {
    location: 'New York',
    units: 'celsius'
  }
});

console.log(result.result.success ? result.result.data : result.result.error);

// Execute multiple tools sequentially
const results = await Promise.all([
  agent.executeTool({ id: 'call-1', name: 'get_weather', parameters: { location: 'Tokyo' } }),
  agent.executeTool({ id: 'call-2', name: 'get_weather', parameters: { location: 'London' } })
]);

Tool-Enhanced Tasks#

Use tools in structured tasks via the Task module:

typescript
const task = await agent.createTask({
  prompt: "Compare the weather in Tokyo, London, and New York",
  useTools: true
});

const result = await agent.executeTask(task.id, {
  stream: true,
  onChunk: (chunk) => {
    console.log(chunk);
  }
});

Tool Context and Metadata#

Tools receive execution context with useful information:

typescript
const contextAwareTool: ToolDefinition = {
  name: 'log_action',
  description: 'Log an action with context',
  parameters: {
    action: {
      name: 'action',
      type: 'string',
      description: 'Action to log',
      required: true
    }
  },
  handler: async (params, context) => {
    // Access execution context
    console.log(`Agent ${context?.agentId} performed: ${params.action}`);
    console.log(`Task ID: ${context?.taskId}`);
    console.log(`User ID: ${context?.userId}`);
    console.log(`Metadata:`, context?.metadata);
    
    return {
      success: true,
      data: { logged: true, timestamp: new Date().toISOString() }
    };
  }
};

Response Types#

Understanding tool execution responses helps you handle results and errors properly.

Tool Execution Response#

Executing a tool returns a ToolCallResult with execution details:

typescript
const result = await agent.executeTool({
  id: "call-123",
  name: "get_weather",
  parameters: {
    location: "Tokyo",
    units: "celsius"
  }
});

// Response structure:
{
  id: "call-123",
  name: "get_weather",
  result: {
    success: true,
    data: {
      temperature: 22,
      conditions: "clear skies",
      location: "Tokyo",
      humidity: 65,
      wind: "5 km/h"
    }
  },
  executionTime: 250  // Execution time in milliseconds
}

Tool Execution with Error#

When a tool fails, the error is included in the result:

typescript
const result = await agent.executeTool({
  id: "call-456",
  name: "get_weather",
  parameters: {
    location: "InvalidCity"
  }
});

// Response with error:
{
  id: "call-456",
  name: "get_weather",
  result: {
    success: false,
    error: "Location 'InvalidCity' not found"
  },
  executionTime: 150
}

Multiple Tool Execution Response#

Executing multiple tools using Promise.all returns an array of results:

typescript
const results = await Promise.all([
  agent.executeTool({ id: "call-1", name: "get_weather", parameters: { location: "Tokyo" } }),
  agent.executeTool({ id: "call-2", name: "get_weather", parameters: { location: "London" } }),
  agent.executeTool({ id: "call-3", name: "search_knowledge", parameters: { query: "climate" } })
]);

// Response structure:
[
  {
    id: "call-1",
    name: "get_weather",
    result: {
      success: true,
      data: { temperature: 22, conditions: "clear" }
    },
    executionTime: 200
  },
  {
    id: "call-2",
    name: "get_weather",
    result: {
      success: true,
      data: { temperature: 15, conditions: "cloudy" }
    },
    executionTime: 220
  },
  {
    id: "call-3",
    name: "search_knowledge",
    result: {
      success: true,
      data: [
        { content: "Climate patterns...", similarity: 0.92 },
        { content: "Global warming...", similarity: 0.85 }
      ]
    },
    executionTime: 180
  }
]

Tool List Response#

Retrieving available tools returns an array of tool definitions:

typescript
const tools = agent.getTools();

// Response structure:
[
  {
    name: "get_weather",
    description: "Get current weather information for a location",
    parameters: {
      location: {
        name: "location",
        type: "string",
        description: "City name or location",
        required: true
      },
      units: {
        name: "units",
        type: "string",
        description: "Temperature units",
        required: false
      }
    },
    handler: [Function]
  },
  {
    name: "search_knowledge",
    description: "Search through the agent's knowledge base",
    parameters: { /* ... */ },
    handler: [Function]
  }
]

Plugin List Response#

Listing registered plugins:

typescript
const plugins = agent.listPlugins();

// Response structure:
[
  {
    name: "weather-plugin",
    version: "1.0.0",
    description: "Weather information tools",
    tools: [ /* ToolDefinition[] */ ],
    initialize: [Function],
    cleanup: [Function]
  },
  {
    name: "data-plugin",
    version: "2.1.0",
    description: "Data processing utilities",
    tools: [ /* ToolDefinition[] */ ]
  }
]