Skip to main content
Version: 2.6

Tool Usage in Reaktors

The @operaide/ai library provides powerful utilities for integrating AI tool calling capabilities into your Reaktors. This guide explains how to use the tool integration aktors to enhance your AI interactions with function calling features.

Overview

Tool calling allows AI models to invoke functions during a conversation, enabling the AI to perform tasks like retrieving data, executing commands, or accessing external systems. The @operaide/ai library offers two main approaches for integrating tools into your Reaktors:

  1. Using aktorTool: For wrapping standalone tools created with the tool function from the ai package
  2. Using aktorToTool: For converting existing aktors into tools accessible to AI models

Core Tool Integration Aktors

  • aktorToolSet: Creates a toolset by combining multiple tools for use with AI models
  • aktorTool: Wraps standalone tools for integration with the aktor framework
  • aktorToTool: Converts existing aktors into tools that can be used with AI models

When to Use aktorTool vs. aktorToTool

Use aktorTool when:

  • You have an existing standalone tool created with the tool function
  • You're building a simple tool that doesn't need to interact with other aktors
  • You want to directly define the tool's behavior without using the aktor pattern

Use aktorToTool when:

  • You want to expose existing aktor functionality as a tool
  • Your tool needs to interact with other aktors or access dependencies
  • You want to maintain separation between the tool interface and the underlying implementation
  • You need to reuse existing aktor logic as a tool

Using aktorTool for Standalone Tools

The aktorTool function wraps a standalone tool created with the tool function from the ai package, making it compatible with the aktor framework.

Example: Weather Tool

This example demonstrates how to create a simple weather tool and integrate it into a Reaktor:

import { aktorConst, aktorSetting, registerReaktorDefinition } from '@operaide/aktor';
import { aktorAICall, aktorAISettingProviderModel, aktorMessagesFromSystemAndUser, aktorToolSet, aktorTool } from '@operaide/ai';
import { z } from 'zod';
import { tool } from 'ai';
import type { LlmOptions } from '@operaide/ai';

// Create a standalone weather tool
const weatherAiTool = tool({
description: 'Get the weather in a location',
parameters: z.object({
location: z.string().describe('The location to get the weather for'),
}),
execute: async ({ location }) => {
console.log(`[Tool Call]: Getting weather for ${location}`);
return {
location,
temperature: 72 + Math.floor(Math.random() * 21) - 10,
};
},
});

registerReaktorDefinition({
reaktorDefinitionId: 'weather-tool-calling',
label: 'Weather Tool Calling Example',
description: 'Demonstrates tool calling with a weather tool',
createReaktor(params) {
// Wrap the standalone tool with aktorTool
const weatherTool = aktorTool(weatherAiTool);

// Create a toolset with the weather tool
const toolBox = aktorToolSet({ weatherTool });

// Set up the AI call with the toolset
const ai = aktorAICall({
messages: aktorMessagesFromSystemAndUser({
user: params.message,
system: aktorSetting(z.string(), 'You are a helpful assistant.', 'System Message'),
}),
providerModel: aktorAISettingProviderModel(),
tools: toolBox,
llmOptions: aktorConst<LlmOptions>({
max_steps: 5,
}),
});

return ai;
},
inputSchema: z.object({
message: z.string().openapi({ example: 'What is the weather in Berlin?' }),
}),
outputSchema: z.string(),
});

Using aktorToTool for Aktor-Based Tools

The aktorToTool function converts an existing aktor into a tool that can be used with AI models, allowing you to expose aktor functionality as tools.

Example: Memory Database Tools

This example demonstrates how to convert database aktors into tools for persisting and retrieving memories:

import { aktorConst, aktorSetting, registerReaktorDefinition } from '@operaide/aktor';
import { z } from 'zod';
import type { LlmOptions } from '@operaide/ai';
import {
aktorAICall,
aktorAISettingProviderModel,
aktorMessagesFromSystemAndUser,
aktorToolSet,
aktorToTool,
} from '@operaide/ai';
import { aktorDatabase } from '@operaide/database';
import { aktorGetMemories, aktorInitMemories, aktorSaveMemory } from '../aktors/memory-db-aktors';

registerReaktorDefinition({
reaktorDefinitionId: 'memory-tool-calling',
label: 'Memory Database Tool Calling',
description: 'Demonstrates tool calling with memory database operations',
createReaktor(params) {
// Set up database
const databaseId = aktorSetting(z.string(), 'your-database-id', 'Database ID');
const db = aktorDatabase({ id: databaseId });
const initializedDb = aktorInitMemories({ client: db });

// Convert saveMemory aktor to a tool
const saveMemoryTool = aktorToTool({
aktor: aktorSaveMemory,
description: 'Persist a fact, thought, information or idea',
parameters: z.object({
memory: z.string().describe('the content to persist'),
}),
dependencies: {
client: initializedDb,
},
});

// Convert getMemories aktor to a tool
const retrieveMemoryTool = aktorToTool({
aktor: aktorGetMemories,
description: 'Retrieve previously persisted facts, thoughts, information or ideas',
parameters: z.object({}),
dependencies: {
client: initializedDb,
},
});

// Create a toolset with both tools
const toolBox = aktorToolSet({ saveMemoryTool, retrieveMemoryTool });

// Set up the AI call with the toolset
const ai = aktorAICall({
messages: aktorMessagesFromSystemAndUser({
user: params.message,
system: aktorSetting(z.string(), 'You are a helpful assistant.', 'System Message'),
}),
providerModel: aktorAISettingProviderModel(),
tools: toolBox,
llmOptions: aktorConst<LlmOptions>({
max_steps: 5,
}),
});

return ai;
},
inputSchema: z.object({
message: z.string().openapi({ example: 'What is my favorite color?' }),
}),
outputSchema: z.string(),
});

The aktorToTool Configuration

When using aktorToTool, you need to provide a configuration object with the following properties:

  • aktor: The aktor factory function to convert to a tool
  • description: A description of the tool for the AI model
  • parameters: A Zod schema defining the parameters the AI model can provide
  • dependencies: External parameters resolved outside the AI call (provided as Aktors)

Parameter Schema

The parameters property defines the schema for parameters that will be provided by the AI model. Use .describe() on each field to provide clear descriptions that help the AI understand how to use the tool:

parameters: z.object({
query: z.string().describe('Search query for finding information'),
limit: z.number().optional().describe('Maximum number of results to return'),
}),

Dependencies

The dependencies property specifies external parameters that will be resolved outside the AI call. These are typically other aktors that the tool depends on:

dependencies: {
database: dbClient,
logger: loggerAktor,
},

Creating a Toolset

Use aktorToolSet to combine multiple tools into a single toolset that can be passed to aktorAICall:

const toolBox = aktorToolSet({
weatherTool, // From aktorTool
saveMemoryTool, // From aktorToTool
retrieveMemoryTool, // From aktorToTool
});

Integrating Tools with AI Calls

To enable AI tool calling, pass the toolset to aktorAICall using the tools parameter:

const ai = aktorAICall({
messages: aktorMessagesFromSystemAndUser({
user: userMessage,
system: systemPrompt,
}),
providerModel: aktorAISettingProviderModel(),
tools: toolBox,
llmOptions: aktorConst<LlmOptions>({
max_steps: 5, // Maximum number of tool calling steps
}),
});

Best Practices

  1. Descriptive Tool Names: Use clear, descriptive names for your tools to help the AI understand their purpose

  2. Detailed Descriptions: Provide detailed descriptions for tools and parameters to guide the AI's usage

  3. Parameter Descriptions: Use .describe() on all Zod schema fields to clarify parameter purposes

  4. Error Handling: Implement proper error handling in your tool execution logic

  5. Tool Granularity: Create focused tools that do one thing well rather than complex multi-purpose tools

  6. Testing: Test your tools independently before integrating them into Reaktors

  7. Limit Tool Steps: Set reasonable limits for max_steps to prevent excessive tool calling

Advanced Tool Patterns

Combining Tool Types

You can mix both aktorTool and aktorToTool in the same Reaktor:

const toolBox = aktorToolSet({
weatherTool: aktorTool(weatherAiTool),
saveMemoryTool: aktorToTool({ ... }),
retrieveMemoryTool: aktorToTool({ ... }),
});

Conclusion

Tool integration in Reaktors provides a powerful way to extend AI capabilities with custom functionality. By understanding when to use aktorTool versus aktorToTool, you can create flexible, maintainable, and powerful AI-powered applications.

Remember:

  • Use aktorTool for standalone tools that don't need aktor integration
  • Use aktorToTool to expose existing aktor functionality as tools
  • Combine tools into a toolset with aktorToolSet
  • Provide the toolset to aktorAICall to enable AI tool calling